From gerrit-no-reply at lists.osmocom.org Thu Sep 1 12:26:47 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 1 Sep 2016 12:26:47 +0000 Subject: osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: Patch Set 2: Hi Holger and Neels, Any updates on these patches? Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 13:37:41 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 13:37:41 +0000 Subject: [MERGED] openbsc[master]: IuPS: add VTY config for asn_debug In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: IuPS: add VTY config for asn_debug ...................................................................... IuPS: add VTY config for asn_debug Add file iu_vty.c in libiu, and iu_vty_init() to initialize the new VTY command: log logging asn1-debug (1|0) Change-Id: If4e7d0ab3fc2ed0cdf4fb0a3fa077a9e34890918 --- M openbsc/include/openbsc/iu.h M openbsc/src/libiu/Makefile.am A openbsc/src/libiu/iu_vty.c 3 files changed, 53 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/iu.h b/openbsc/include/openbsc/iu.h index d0ab540..f973ac1 100644 --- a/openbsc/include/openbsc/iu.h +++ b/openbsc/include/openbsc/iu.h @@ -58,3 +58,5 @@ 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); + +void iu_vty_init(int *asn_debug_p); diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 7b1ba4d..1968d3e 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -6,5 +6,5 @@ noinst_LIBRARIES = libiu.a -libiu_a_SOURCES = iu.c +libiu_a_SOURCES = iu.c iu_vty.c diff --git a/openbsc/src/libiu/iu_vty.c b/openbsc/src/libiu/iu_vty.c new file mode 100644 index 0000000..91eed96 --- /dev/null +++ b/openbsc/src/libiu/iu_vty.c @@ -0,0 +1,50 @@ +/* OpenBSC Iu related interface to quagga VTY */ +/* (C) 2016 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * 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 . + * + */ + +#include + +#include +#include + +/* Pointer to the actual asn_debug value as passed from main scopes. */ +static int *g_asn_debug_p = NULL; + +DEFUN(logging_asn_debug, + logging_asn_debug_cmd, + "logging asn1-debug (1|0)", + LOGGING_STR + "Log human readable representations of all ASN.1 messages to stderr\n" + "Log decoded ASN.1 messages to stderr\n" + "Do not log decoded ASN.1 messages to stderr\n") +{ + if (!g_asn_debug_p) { + vty_out(vty, "%%ASN.1 debugging not available%s", VTY_NEWLINE); + return CMD_WARNING; + } + + *g_asn_debug_p = atoi(argv[0]); + return CMD_SUCCESS; +} + +void iu_vty_init(int *asn_debug_p) +{ + g_asn_debug_p = asn_debug_p; + + install_element(CFG_LOG_NODE, &logging_asn_debug_cmd); +} -- To view, visit https://gerrit.osmocom.org/790 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If4e7d0ab3fc2ed0cdf4fb0a3fa077a9e34890918 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 1 13:41:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 13:41:37 +0000 Subject: [PATCH] openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/729 to look at the new patch set (#6). IuPS: osmo-sgsn: add core IuPS impl, call iu_init() Add: * gsm0408_gprs_rcvmsg_iu() * sgsn_mm_ctx_by_ue_ctx() * sgsn_mm_ctx_alloc_iu() * sgsn_ranap_iu_event() * sgsn_ranap_rab_ass_resp() Call iu_init() from sgsn_main.c. Add asn_debug impl ("extern" from libasn1c). osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_main.c 7 files changed, 237 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/29/729/6 diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 8a3ffea..28467d7 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -14,6 +14,8 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable); +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, struct gprs_llc_llme *llme); diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index b0dd75f..18cbab8 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -226,6 +226,7 @@ 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, @@ -234,6 +235,8 @@ /* Allocate a new SGSN MM context */ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, const struct gprs_ra_id *raid); +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, diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 1b6de46..6a95315 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -3,6 +3,10 @@ $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \ $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif + OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) @@ -28,9 +32,15 @@ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ + $(top_builddir)/src/libcommon/libcommon.a +if BUILD_IU +osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a +endif +osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) -lrt +if BUILD_IU +osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +endif osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \ gtphub_vty.c sgsn_ares.c gprs_utils.c diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 1efada9..4c44224 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -33,6 +33,8 @@ #include +#include "bscconfig.h" + #include #include #include @@ -44,6 +46,10 @@ #include #include + +#ifdef BUILD_IU +#include +#endif #include #include @@ -57,6 +63,10 @@ #include #include #include + +#ifdef BUILD_IU +#include +#endif #include @@ -96,6 +106,45 @@ }; static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); + +#ifdef BUILD_IU +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) +{ + struct sgsn_mm_ctx *mm; + int rc = -1; + + mm = sgsn_mm_ctx_by_ue_ctx(ctx); + if (!mm) { + LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type); + return rc; + } + + switch (type) { + case IU_EVENT_RAB_ASSIGN: + rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); + break; + case IU_EVENT_IU_RELEASE: + /* fall thru */ + case IU_EVENT_LINK_INVALIDATED: + /* Clean up ue_conn_ctx here */ + LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + rc = 0; + break; + case IU_EVENT_SECURITY_MODE_COMPLETE: + /* Continue authentication here */ + mm->iu.ue_ctx->integrity_active = 1; + rc = gsm48_gmm_authorize(mm); + break; + default: + LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); + rc = -1; + break; + } + return rc; +} +#endif + /* Our implementation, should be kept in SGSN */ @@ -2193,6 +2242,45 @@ return rc; } +/* Main entry point for incoming 04.08 GPRS messages from Iu */ +int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, + uint16_t *sai) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t pdisc = gsm48_hdr_pdisc(gh); + struct sgsn_mm_ctx *mmctx; + int rc = -EINVAL; + + mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst); + if (mmctx) { + rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); + if (ra_id) + memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra)); + } + + /* MMCTX can be NULL */ + + switch (pdisc) { + case GSM48_PDISC_MM_GPRS: + rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false); +#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?" + break; + case GSM48_PDISC_SM_GPRS: + rc = gsm0408_rcv_gsm(mmctx, msg, NULL); + break; + default: + LOGMMCTXP(LOGL_NOTICE, mmctx, + "Unknown GSM 04.08 discriminator 0x%02x: %s\n", + pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); + /* FIXME: return status message */ + break; + } + + /* MMCTX can be invalid */ + + return rc; +} + /* Main entry point for incoming 04.08 GPRS messages from Gb */ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 9cd992b..19b0a1b 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -39,6 +39,7 @@ #include #include #include "openbsc/gprs_llc.h" +#include #include @@ -130,6 +131,20 @@ sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0); } +/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx) +{ + struct sgsn_mm_ctx *ctx; + + 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 */ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, const struct gprs_ra_id *raid) @@ -218,6 +233,32 @@ 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->mm_state = GMM_DEREGISTERED; + 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! */ static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..4a14cf6 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -34,6 +34,8 @@ #include #include +#include "bscconfig.h" + #include #include #include @@ -47,6 +49,11 @@ #include #include #include + +#ifdef BUILD_IU +#include +#include +#endif #include #include @@ -218,7 +225,10 @@ memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - /* SGSN address for user plane */ + /* SGSN address for user plane + * Default to the control plane addr for now. If we are connected to a + * hnbgw via IuPS we'll need to send a PDP context update with the + * correct IP address after the RAB Assignment is complete */ pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); @@ -383,6 +393,72 @@ return EOF; } +#ifdef BUILD_IU +/* Callback for RAB assignment response */ +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) +{ + uint8_t rab_id; + bool require_pdp_update = false; + struct sgsn_pdp_ctx *pdp = NULL; + RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; + + rab_id = item->rAB_ID.buf[0]; + + pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id); + if (!pdp) { + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id); + return -1; + } + + if (item->transportLayerAddress) { + LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf, + item->transportLayerAddress->size)); + switch (item->transportLayerAddress->size) { + case 7: + /* It must be IPv4 inside a X213 NSAP */ + memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4); + break; + case 4: + /* It must be a raw IPv4 address */ + memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4); + break; + case 16: + /* TODO: It must be a raw IPv6 address */ + case 19: + /* TODO: It must be IPv6 inside a X213 NSAP */ + default: + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown " + "transport layer address size %u\n", + item->transportLayerAddress->size); + return -1; + } + require_pdp_update = true; + } + + /* The TEI on the RNC side might have changed, too */ + if (item->iuTransportAssociation && + item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI && + item->iuTransportAssociation->choice.gTP_TEI.buf && + item->iuTransportAssociation->choice.gTP_TEI.size >= 4) { + uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf); + LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n", + pdp->lib->teid_own, tei); + pdp->lib->teid_own = tei; + require_pdp_update = true; + } + + if (require_pdp_update) + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); + + if (pdp->state != PDP_STATE_CR_CONF) { + send_act_pdp_cont_acc(pdp); + pdp->state = PDP_STATE_CR_CONF; + } + return 0; + +} +#endif + /* Confirmation of a PDP Context Delete */ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..0cea584 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -56,6 +56,8 @@ #include #include #include +#include + #include #include @@ -300,6 +302,13 @@ .num_cat = ARRAY_SIZE(gprs_categories), }; +/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1 + * binary code decoded and encoded during Iu communication should be logged to + * stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)": + * http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */ +int asn_debug = 0; + +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data); int main(int argc, char **argv) { @@ -326,6 +335,7 @@ osmo_stats_vty_add_cmds(&gprs_log_info); sgsn_vty_init(); ctrl_vty_init(tall_bsc_ctx); + iu_vty_init(&asn_debug); handle_options(argc, argv); @@ -417,6 +427,10 @@ } } +#ifdef BUILD_IU + iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); +#endif + if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Thu Sep 1 13:44:29 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 13:44:29 +0000 Subject: openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 re-adding earlier +2 score, lost due to rebase with trivial changes. -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 13:46:14 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 13:46:14 +0000 Subject: openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Patch Set 6: Code-Review-1 Stop! by accident, I re-uploaded an older patch version! -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 13:48:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 13:48:51 +0000 Subject: openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Patch Set 6: I'll have to fix this later today. -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 15:13:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 15:13:11 +0000 Subject: osmo-bts[master]: dyn TS: if PCU is not connected, allow operation as TCH In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/748/2/src/common/rsl.c File src/common/rsl.c: PS2, Line 930: o for the BSC, it is not : * helpful in any way to know that a PDCH channel fails to : * work > this is not entirely true. For OML/OSS it is important to understand that The wording might be a bit too drastic, but: My point is that normal PDCH operation has no such OML alerts. Also, this is about RSL Chan Activ messages, and not OML. I see your point and it would probably be good to add reporting, but I'd first like to get dyn TS working like normal PDCH, i.e. as if they did not appear on the RSL channel activation. There's also the case of activating PDCH when the PCU is not running yet, which basically happens at every BTS startup. The BTS starts, the PCU must not yet be running. Then the channels are setup (and for dyn TS the non-standard RSL Chan Act for PDCH mode is sent); the PCU will only start in a few seconds' time. In that case we'd have to send some RSL failure back to the BSC, where in the default case the PCU will come up shortly and the PDCH channels will simply start working. So it makes no sense to nack at startup. Determining whether the PCU is considered ok is not trivial. We'd need to define some timeout (half a minute?) and check whether a PDCH has not become active in that period. But the RSL logic expects an ack fairly quickly, or it will put the channel in a broken state. At this point, I prefer to cut out the complexity by just not telling the RSL wire anything about PDCH except "ack, all is fine, don't worry now"; like standard PDCH. Let's have reporting of PDCH failure as an OS# feature request? -- To view, visit https://gerrit.osmocom.org/748 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:24:52 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:24:52 +0000 Subject: [PATCH] openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/729 to look at the new patch set (#7). IuPS: osmo-sgsn: add core IuPS impl, call iu_init() Add: * gsm0408_gprs_rcvmsg_iu() * sgsn_mm_ctx_by_ue_ctx() * sgsn_mm_ctx_alloc_iu() * sgsn_ranap_iu_event() * sgsn_ranap_rab_ass_resp() Call iu_init() from sgsn_main.c. Add asn_debug impl ("extern" from libasn1c). Initialize asn_debug VTY command (iu_vty_init()). osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_main.c 7 files changed, 239 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/29/729/7 diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 8a3ffea..28467d7 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -14,6 +14,8 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable); +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, struct gprs_llc_llme *llme); diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index b0dd75f..18cbab8 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -226,6 +226,7 @@ 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, @@ -234,6 +235,8 @@ /* Allocate a new SGSN MM context */ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, const struct gprs_ra_id *raid); +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, diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 1b6de46..6a95315 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -3,6 +3,10 @@ $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \ $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif + OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) @@ -28,9 +32,15 @@ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ + $(top_builddir)/src/libcommon/libcommon.a +if BUILD_IU +osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a +endif +osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) -lrt +if BUILD_IU +osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +endif osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \ gtphub_vty.c sgsn_ares.c gprs_utils.c diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 1efada9..4c44224 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -33,6 +33,8 @@ #include +#include "bscconfig.h" + #include #include #include @@ -44,6 +46,10 @@ #include #include + +#ifdef BUILD_IU +#include +#endif #include #include @@ -57,6 +63,10 @@ #include #include #include + +#ifdef BUILD_IU +#include +#endif #include @@ -96,6 +106,45 @@ }; static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); + +#ifdef BUILD_IU +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) +{ + struct sgsn_mm_ctx *mm; + int rc = -1; + + mm = sgsn_mm_ctx_by_ue_ctx(ctx); + if (!mm) { + LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type); + return rc; + } + + switch (type) { + case IU_EVENT_RAB_ASSIGN: + rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); + break; + case IU_EVENT_IU_RELEASE: + /* fall thru */ + case IU_EVENT_LINK_INVALIDATED: + /* Clean up ue_conn_ctx here */ + LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + rc = 0; + break; + case IU_EVENT_SECURITY_MODE_COMPLETE: + /* Continue authentication here */ + mm->iu.ue_ctx->integrity_active = 1; + rc = gsm48_gmm_authorize(mm); + break; + default: + LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); + rc = -1; + break; + } + return rc; +} +#endif + /* Our implementation, should be kept in SGSN */ @@ -2193,6 +2242,45 @@ return rc; } +/* Main entry point for incoming 04.08 GPRS messages from Iu */ +int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, + uint16_t *sai) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t pdisc = gsm48_hdr_pdisc(gh); + struct sgsn_mm_ctx *mmctx; + int rc = -EINVAL; + + mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst); + if (mmctx) { + rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); + if (ra_id) + memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra)); + } + + /* MMCTX can be NULL */ + + switch (pdisc) { + case GSM48_PDISC_MM_GPRS: + rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false); +#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?" + break; + case GSM48_PDISC_SM_GPRS: + rc = gsm0408_rcv_gsm(mmctx, msg, NULL); + break; + default: + LOGMMCTXP(LOGL_NOTICE, mmctx, + "Unknown GSM 04.08 discriminator 0x%02x: %s\n", + pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); + /* FIXME: return status message */ + break; + } + + /* MMCTX can be invalid */ + + return rc; +} + /* Main entry point for incoming 04.08 GPRS messages from Gb */ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 9cd992b..19b0a1b 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -39,6 +39,7 @@ #include #include #include "openbsc/gprs_llc.h" +#include #include @@ -130,6 +131,20 @@ sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0); } +/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx) +{ + struct sgsn_mm_ctx *ctx; + + 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 */ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, const struct gprs_ra_id *raid) @@ -218,6 +233,32 @@ 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->mm_state = GMM_DEREGISTERED; + 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! */ static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..4a14cf6 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -34,6 +34,8 @@ #include #include +#include "bscconfig.h" + #include #include #include @@ -47,6 +49,11 @@ #include #include #include + +#ifdef BUILD_IU +#include +#include +#endif #include #include @@ -218,7 +225,10 @@ memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - /* SGSN address for user plane */ + /* SGSN address for user plane + * Default to the control plane addr for now. If we are connected to a + * hnbgw via IuPS we'll need to send a PDP context update with the + * correct IP address after the RAB Assignment is complete */ pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); @@ -383,6 +393,72 @@ return EOF; } +#ifdef BUILD_IU +/* Callback for RAB assignment response */ +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) +{ + uint8_t rab_id; + bool require_pdp_update = false; + struct sgsn_pdp_ctx *pdp = NULL; + RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; + + rab_id = item->rAB_ID.buf[0]; + + pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id); + if (!pdp) { + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id); + return -1; + } + + if (item->transportLayerAddress) { + LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf, + item->transportLayerAddress->size)); + switch (item->transportLayerAddress->size) { + case 7: + /* It must be IPv4 inside a X213 NSAP */ + memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4); + break; + case 4: + /* It must be a raw IPv4 address */ + memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4); + break; + case 16: + /* TODO: It must be a raw IPv6 address */ + case 19: + /* TODO: It must be IPv6 inside a X213 NSAP */ + default: + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown " + "transport layer address size %u\n", + item->transportLayerAddress->size); + return -1; + } + require_pdp_update = true; + } + + /* The TEI on the RNC side might have changed, too */ + if (item->iuTransportAssociation && + item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI && + item->iuTransportAssociation->choice.gTP_TEI.buf && + item->iuTransportAssociation->choice.gTP_TEI.size >= 4) { + uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf); + LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n", + pdp->lib->teid_own, tei); + pdp->lib->teid_own = tei; + require_pdp_update = true; + } + + if (require_pdp_update) + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); + + if (pdp->state != PDP_STATE_CR_CONF) { + send_act_pdp_cont_acc(pdp); + pdp->state = PDP_STATE_CR_CONF; + } + return 0; + +} +#endif + /* Confirmation of a PDP Context Delete */ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..7d533c0 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -56,6 +56,8 @@ #include #include #include +#include + #include #include @@ -300,6 +302,13 @@ .num_cat = ARRAY_SIZE(gprs_categories), }; +/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1 + * binary code decoded and encoded during Iu communication should be logged to + * stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)": + * http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */ +int asn_debug = 0; + +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data); int main(int argc, char **argv) { @@ -326,6 +335,9 @@ osmo_stats_vty_add_cmds(&gprs_log_info); sgsn_vty_init(); ctrl_vty_init(tall_bsc_ctx); +#ifdef BUILD_IU + iu_vty_init(&asn_debug); +#endif handle_options(argc, argv); @@ -417,6 +429,10 @@ } } +#ifdef BUILD_IU + iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); +#endif + if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:32:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:32:22 +0000 Subject: [PATCH] openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/734 to look at the new patch set (#7). IuPS: dev hack: init hardcoded Ki on ATT REQ DEVELOPMENT HACK: Our current HLR does not support 3G authentication tokens. A new HLR/VLR implementation is being developed. Until it is ready and actual milenage authentication is properly supported, we are hardcoding a fixed Ki and use 2G auth. Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/34/734/7 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8b8bdd1..7d00bd5 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1039,6 +1040,34 @@ ctx->ra = ra_id; if (ctx->ran_type == MM_CTX_T_GERAN_Gb) ctx->gb.cell_id = cid; + else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) { + /* DEVELOPMENT HACK: Our current HLR does not support 3G + * authentication tokens. A new HLR/VLR implementation is being + * developed. Until it is ready and actual milenage + * authentication is properly supported, we are hardcoding a + * fixed Ki and use 2G auth. */ + unsigned char tmp_rand[16]; + /* Ki 000102030405060708090a0b0c0d0e0f */ + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1, + .u.gsm.ki = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + }; + /* XXX: Hack to make 3G auth work with special SIM card */ + ctx->auth_state = SGSN_AUTH_AUTHENTICATE; + + RAND_bytes(tmp_rand, 16); + + memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec)); + osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand); + + ctx->auth_triplet.key_seq = 0; + } + /* Update MM Context with other data */ ctx->drx_parms = drx_par; ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:34:16 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:34:16 +0000 Subject: openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Patch Set 7: We could also decide to not merge this until the new HLR is ready. It's not going to take too long anymore (TM), right? -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: add GMM Service Request rx and tx In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/737 to look at the new patch set (#8). IuPS: add GMM Service Request rx and tx Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 199 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/37/737/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 14043ce..b515abd 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -690,6 +690,75 @@ strncpy(&ctx->hlr[0], called.number, sizeof(ctx->hlr) - 1); } +#ifdef BUILD_IU +/* Chapter 9.4.21: Service accept */ +static int gsm48_tx_gmm_service_ack(struct sgsn_mm_ctx *mm) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE ACK"); + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_INFO, mm, "<- GPRS SERVICE ACCEPT (P-TMSI=0x%08x)\n", mm->p_tmsi); + + mmctx2msgid(msg, mm); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_ACK; + + /* Optional: PDP context status */ + /* Optional: MBMS context status */ + + return gsm48_gmm_sendmsg(msg, 0, mm, false); +} +#endif + +/* Chapter 9.4.22: Service reject */ +static int _tx_gmm_service_rej(struct msgb *msg, uint8_t gmm_cause, + const struct sgsn_mm_ctx *mm) +{ + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS SERVICE REJECT: %s\n", + get_value_string(gsm48_gmm_cause_names, gmm_cause)); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_REJ; + gh->data[0] = gmm_cause; + + return gsm48_gmm_sendmsg(msg, 0, NULL, true); +} +static int gsm48_tx_gmm_service_rej_oldmsg(const struct msgb *old_msg, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ OLD"); + gmm_copy_id(msg, old_msg); + return _tx_gmm_service_rej(msg, gmm_cause, NULL); +} +#if 0 +-- currently unused -- +static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ"); + mmctx2msgid(msg, mm); + return _tx_gmm_service_rej(msg, gmm_cause, mm); +} +#endif + +static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm); + +#ifdef BUILD_IU +void activate_pdp_rabs(struct sgsn_mm_ctx *ctx) +{ + /* Send RAB activation requests for all PDP contexts */ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &ctx->pdp_list, list) { + iu_rab_act_ps(pdp->nsapi, pdp, 1); + } +} +#endif + /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { @@ -778,6 +847,23 @@ #endif return gsm48_tx_gmm_att_ack(ctx); +#ifdef BUILD_IU + case GSM48_MT_GMM_SERVICE_REQ: + /* TODO: PMM State transition */ + ctx->pending_req = 0; + rc = gsm48_tx_gmm_service_ack(ctx); + + if (ctx->iu.service.type == 1) { + activate_pdp_rabs(ctx); + } + + return rc; +#endif + case GSM48_MT_GMM_RA_UPD_REQ: + ctx->pending_req = 0; + /* Send RA UPDATE ACCEPT */ + return gsm48_tx_gmm_ra_upd_ack(ctx); + default: LOGMMCTXP(LOGL_ERROR, ctx, "only Attach Request is supported yet, " @@ -1473,6 +1559,116 @@ return rc; } +/* 3GPP TS 24.008 Section 9.4.20 Service request. + * In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back + * to PMM-CONNECTED mode. */ +static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t *cur = gh->data, *mi; + uint8_t ciph_seq_nr, service_type, mi_len, mi_type; + uint32_t tmsi; + struct tlv_parsed tp; + char mi_string[GSM48_MI_SIZE]; + enum gsm48_gmm_cause reject_cause; + int rc; + + LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST "); + + /* This message is only valid in Iu mode */ + if (!msg->dst) { + LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n"); + return -1; + } + + /* Skip Ciphering key sequence number 10.5.1.2 */ + ciph_seq_nr = *cur & 0x07; + + /* Service type 10.5.5.20 */ + service_type = (*cur++ >> 4) & 0x07; + + /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ + mi_len = *cur++; + mi = cur; + if (mi_len > 8) + goto err_inval; + mi_type = *mi & GSM_MI_TYPE_MASK; + cur += mi_len; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + + DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string, + get_value_string(gprs_service_t_strs, service_type)); + + LOGPC(DMM, LOGL_INFO, "\n"); + + /* Optional: PDP context status, MBMS context status, Uplink data status, Device properties */ + tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, (msg->data + msg->len) - cur, 0, 0); + + switch (mi_type) { + case GSM_MI_TYPE_IMSI: + /* Try to find MM context based on IMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_imsi(mi_string); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + case GSM_MI_TYPE_TMSI: + memcpy(&tmsi, mi+1, 4); + tmsi = ntohl(tmsi); + /* Try to find MM context based on P-TMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_ptmsi(tmsi); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + default: + LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting SERVICE REQUEST with " + "MI type %s\n", gsm48_mi_type_name(mi_type)); + reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; + goto rejected; + } + + ctx->mm_state = GMM_COMMON_PROC_INIT; + + ctx->iu.service.type = service_type; + + /* TODO: Handle those only in case of accept? */ + /* Look at PDP Context Status IE and see if MS's view of + * activated/deactivated NSAPIs agrees with our view */ + if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) { + const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS); + process_ms_ctx_status(ctx, pdp_status); + } + + + ctx->pending_req = GSM48_MT_GMM_SERVICE_REQ; + return gsm48_gmm_authorize(ctx); + +err_inval: + LOGPC(DMM, LOGL_INFO, "\n"); + reject_cause = GMM_CAUSE_SEM_INCORR_MSG; + +rejected: + /* Send SERVICE REJECT */ + LOGMMCTXP(LOGL_NOTICE, ctx, + "Rejecting Service Request with cause '%s' (%d)\n", + get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); + rc = gsm48_tx_gmm_service_rej_oldmsg(msg, reject_cause); + + return rc; + +} + + static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); @@ -1551,6 +1747,9 @@ case GSM48_MT_GMM_ATTACH_REQ: rc = gsm48_rx_gmm_att_req(mmctx, msg, llme); break; + case GSM48_MT_GMM_SERVICE_REQ: + rc = gsm48_rx_gmm_service_req(mmctx, msg); + break; /* For all the following types mmctx can not be NULL */ case GSM48_MT_GMM_ID_RESP: if (!mmctx) -- To view, visit https://gerrit.osmocom.org/737 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: RA UPD: make sure to authorize, for Iu Integrity Prote... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/738 to look at the new patch set (#8). IuPS: RA UPD: make sure to authorize, for Iu Integrity Protection Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 7 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/738/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index b515abd..53b6322 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -50,6 +50,7 @@ #ifdef BUILD_IU #include +#include #endif #include @@ -853,9 +854,8 @@ ctx->pending_req = 0; rc = gsm48_tx_gmm_service_ack(ctx); - if (ctx->iu.service.type == 1) { + if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) activate_pdp_rabs(ctx); - } return rc; #endif @@ -1540,8 +1540,11 @@ process_ms_ctx_status(mmctx, pdp_status); } - /* Send RA UPDATE ACCEPT */ - return gsm48_tx_gmm_ra_upd_ack(mmctx); + /* Send RA UPDATE ACCEPT. In Iu, the RA upd request can be called from + * a new Iu connection, so we might need to re-authenticate the + * connection as well as turn on integrity protection. */ + mmctx->pending_req = GSM48_MT_GMM_RA_UPD_REQ; + return gsm48_gmm_authorize(mmctx); rejected: /* Send RA UPDATE REJECT */ -- To view, visit https://gerrit.osmocom.org/738 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM ... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/739 to look at the new patch set (#8). IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM state Iu needs to page to transfer data in PMM-IDLE state. Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 --- M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 3 files changed, 18 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/739/8 diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 18cbab8..24e286c 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -31,6 +31,16 @@ 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, @@ -117,6 +127,7 @@ char imsi[GSM23003_IMSI_MAX_DIGITS+1]; enum gprs_gmm_state mm_state; + enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ uint32_t p_tmsi; uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ uint32_t p_tmsi_sig; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 53b6322..99e4a8c 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -131,6 +131,8 @@ case IU_EVENT_LINK_INVALIDATED: /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + if (mm->pmm_state == PMM_CONNECTED) + mm->pmm_state = PMM_IDLE; rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -241,6 +243,7 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; + ctx->pmm_state = PMM_DETACHED; sgsn_mm_ctx_cleanup_free(ctx); } @@ -852,6 +855,7 @@ case GSM48_MT_GMM_SERVICE_REQ: /* TODO: PMM State transition */ ctx->pending_req = 0; + ctx->pmm_state = PMM_CONNECTED; rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1793,6 +1797,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1815,6 +1820,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index dd7e008..e5a54d9 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -246,6 +246,7 @@ 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); -- To view, visit https://gerrit.osmocom.org/739 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: GMM Attach: reset MM ctx pending_req In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/740 to look at the new patch set (#8). IuPS: GMM Attach: reset MM ctx pending_req Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/40/740/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 99e4a8c..c17d813 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -836,6 +836,7 @@ "no pending request, authorization completed\n"); break; case GSM48_MT_GMM_ATTACH_REQ: + ctx->pending_req = 0; extract_subscr_msisdn(ctx); extract_subscr_hlr(ctx); -- To view, visit https://gerrit.osmocom.org/740 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: Introduce function to change PMM state In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/741 to look at the new patch set (#8). IuPS: Introduce function to change PMM state This is where IuPS will redirect GTP-U endpoints in a subsequent commit. Also add comprehensive logging of pmm_state transitions. Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/41/741/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index c17d813..cb3d4ee 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,29 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) +{ + if (ctx->pmm_state == state) + return; + + LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %i to %i\n", ctx->pmm_state, state); + + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + { + switch (state) { + case PMM_IDLE: + /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + break; + case PMM_CONNECTED: + break; + default: + break; + } + } + + ctx->pmm_state = state; +} + #ifdef BUILD_IU int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) @@ -132,7 +155,7 @@ /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); if (mm->pmm_state == PMM_CONNECTED) - mm->pmm_state = PMM_IDLE; + mmctx_set_pmm_state(mm, PMM_IDLE); rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -243,7 +266,8 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; - ctx->pmm_state = PMM_DETACHED; + + mmctx_set_pmm_state(ctx, PMM_DETACHED); sgsn_mm_ctx_cleanup_free(ctx); } @@ -854,9 +878,8 @@ return gsm48_tx_gmm_att_ack(ctx); #ifdef BUILD_IU case GSM48_MT_GMM_SERVICE_REQ: - /* TODO: PMM State transition */ ctx->pending_req = 0; - ctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(ctx, PMM_CONNECTED); rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1798,7 +1821,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1821,7 +1844,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); -- To view, visit https://gerrit.osmocom.org/741 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE ... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/742 to look at the new patch set (#8). IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE when data arrives Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b --- M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 3 files changed, 32 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/742/8 diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..22809b7 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -138,6 +138,7 @@ uint16_t nsapi, struct tlv_parsed *tp); int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); /* gprs_sndcp.c */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index cb3d4ee..3d74647 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,16 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx) +{ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) { + sgsn_pdp_upd_gtp_u(pdp, + &sgsn->cfg.gtp_listenaddr.sin_addr, + sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); + } +} + void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) { if (ctx->pmm_state == state) @@ -120,7 +130,8 @@ { switch (state) { case PMM_IDLE: - /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + /* TODO: start RA Upd timer */ + mmctx_change_gtpu_endpoints_to_sgsn(ctx); break; case PMM_CONNECTED: break; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 35d5dab..04bd40a 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -401,6 +401,13 @@ return EOF; } +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen) +{ + pdp->lib->gsnlu.l = alen; + memcpy(pdp->lib->gsnlu.v, addr, alen); + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); +} + #ifdef BUILD_IU /* Callback for RAB assignment response */ int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) @@ -621,6 +628,18 @@ return -EIO; } + if (mm->ran_type == MM_CTX_T_UTRAN_Iu) { +#ifdef BUILD_IU + /* Ignore the packet for now and page the UE to get the RAB + * reestablished */ + iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac, mm->ra.rac); + + return 0; +#else + return -ENOTSUP; +#endif + } + msg = msgb_alloc_headroom(len+256, 128, "GTP->SNDCP"); ud = msgb_put(msg, len); memcpy(ud, packet, len); -- To view, visit https://gerrit.osmocom.org/742 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/729 to look at the new patch set (#8). IuPS: osmo-sgsn: add core IuPS impl, call iu_init() Add main Iu entry points for IuPS: * gsm0408_gprs_rcvmsg_iu() * sgsn_ranap_iu_event() * sgsn_ranap_rab_ass_resp() Add main MM context management for IuPS: * sgsn_mm_ctx_by_ue_ctx() * sgsn_mm_ctx_alloc_iu() Call iu_init() from sgsn_main.c. Add asn_debug impl ("extern" from libasn1c). Initialize asn_debug VTY command (iu_vty_init()). osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_main.c 7 files changed, 239 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/29/729/8 diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 8a3ffea..28467d7 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -14,6 +14,8 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable); +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, struct gprs_llc_llme *llme); diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index b0dd75f..18cbab8 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -226,6 +226,7 @@ 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, @@ -234,6 +235,8 @@ /* Allocate a new SGSN MM context */ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, const struct gprs_ra_id *raid); +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, diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 1b6de46..6a95315 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -3,6 +3,10 @@ $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \ $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif + OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) @@ -28,9 +32,15 @@ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ + $(top_builddir)/src/libcommon/libcommon.a +if BUILD_IU +osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a +endif +osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) -lrt +if BUILD_IU +osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +endif osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \ gtphub_vty.c sgsn_ares.c gprs_utils.c diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 1efada9..4c44224 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -33,6 +33,8 @@ #include +#include "bscconfig.h" + #include #include #include @@ -44,6 +46,10 @@ #include #include + +#ifdef BUILD_IU +#include +#endif #include #include @@ -57,6 +63,10 @@ #include #include #include + +#ifdef BUILD_IU +#include +#endif #include @@ -96,6 +106,45 @@ }; static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); + +#ifdef BUILD_IU +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) +{ + struct sgsn_mm_ctx *mm; + int rc = -1; + + mm = sgsn_mm_ctx_by_ue_ctx(ctx); + if (!mm) { + LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type); + return rc; + } + + switch (type) { + case IU_EVENT_RAB_ASSIGN: + rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); + break; + case IU_EVENT_IU_RELEASE: + /* fall thru */ + case IU_EVENT_LINK_INVALIDATED: + /* Clean up ue_conn_ctx here */ + LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + rc = 0; + break; + case IU_EVENT_SECURITY_MODE_COMPLETE: + /* Continue authentication here */ + mm->iu.ue_ctx->integrity_active = 1; + rc = gsm48_gmm_authorize(mm); + break; + default: + LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); + rc = -1; + break; + } + return rc; +} +#endif + /* Our implementation, should be kept in SGSN */ @@ -2193,6 +2242,45 @@ return rc; } +/* Main entry point for incoming 04.08 GPRS messages from Iu */ +int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, + uint16_t *sai) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t pdisc = gsm48_hdr_pdisc(gh); + struct sgsn_mm_ctx *mmctx; + int rc = -EINVAL; + + mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst); + if (mmctx) { + rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); + if (ra_id) + memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra)); + } + + /* MMCTX can be NULL */ + + switch (pdisc) { + case GSM48_PDISC_MM_GPRS: + rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false); +#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?" + break; + case GSM48_PDISC_SM_GPRS: + rc = gsm0408_rcv_gsm(mmctx, msg, NULL); + break; + default: + LOGMMCTXP(LOGL_NOTICE, mmctx, + "Unknown GSM 04.08 discriminator 0x%02x: %s\n", + pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); + /* FIXME: return status message */ + break; + } + + /* MMCTX can be invalid */ + + return rc; +} + /* Main entry point for incoming 04.08 GPRS messages from Gb */ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 9cd992b..19b0a1b 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -39,6 +39,7 @@ #include #include #include "openbsc/gprs_llc.h" +#include #include @@ -130,6 +131,20 @@ sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0); } +/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx) +{ + struct sgsn_mm_ctx *ctx; + + 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 */ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, const struct gprs_ra_id *raid) @@ -218,6 +233,32 @@ 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->mm_state = GMM_DEREGISTERED; + 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! */ static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..4a14cf6 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -34,6 +34,8 @@ #include #include +#include "bscconfig.h" + #include #include #include @@ -47,6 +49,11 @@ #include #include #include + +#ifdef BUILD_IU +#include +#include +#endif #include #include @@ -218,7 +225,10 @@ memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - /* SGSN address for user plane */ + /* SGSN address for user plane + * Default to the control plane addr for now. If we are connected to a + * hnbgw via IuPS we'll need to send a PDP context update with the + * correct IP address after the RAB Assignment is complete */ pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); @@ -383,6 +393,72 @@ return EOF; } +#ifdef BUILD_IU +/* Callback for RAB assignment response */ +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) +{ + uint8_t rab_id; + bool require_pdp_update = false; + struct sgsn_pdp_ctx *pdp = NULL; + RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; + + rab_id = item->rAB_ID.buf[0]; + + pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id); + if (!pdp) { + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id); + return -1; + } + + if (item->transportLayerAddress) { + LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf, + item->transportLayerAddress->size)); + switch (item->transportLayerAddress->size) { + case 7: + /* It must be IPv4 inside a X213 NSAP */ + memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4); + break; + case 4: + /* It must be a raw IPv4 address */ + memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4); + break; + case 16: + /* TODO: It must be a raw IPv6 address */ + case 19: + /* TODO: It must be IPv6 inside a X213 NSAP */ + default: + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown " + "transport layer address size %u\n", + item->transportLayerAddress->size); + return -1; + } + require_pdp_update = true; + } + + /* The TEI on the RNC side might have changed, too */ + if (item->iuTransportAssociation && + item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI && + item->iuTransportAssociation->choice.gTP_TEI.buf && + item->iuTransportAssociation->choice.gTP_TEI.size >= 4) { + uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf); + LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n", + pdp->lib->teid_own, tei); + pdp->lib->teid_own = tei; + require_pdp_update = true; + } + + if (require_pdp_update) + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); + + if (pdp->state != PDP_STATE_CR_CONF) { + send_act_pdp_cont_acc(pdp); + pdp->state = PDP_STATE_CR_CONF; + } + return 0; + +} +#endif + /* Confirmation of a PDP Context Delete */ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..7d533c0 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -56,6 +56,8 @@ #include #include #include +#include + #include #include @@ -300,6 +302,13 @@ .num_cat = ARRAY_SIZE(gprs_categories), }; +/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1 + * binary code decoded and encoded during Iu communication should be logged to + * stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)": + * http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */ +int asn_debug = 0; + +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data); int main(int argc, char **argv) { @@ -326,6 +335,9 @@ osmo_stats_vty_add_cmds(&gprs_log_info); sgsn_vty_init(); ctrl_vty_init(tall_bsc_ctx); +#ifdef BUILD_IU + iu_vty_init(&asn_debug); +#endif handle_options(argc, argv); @@ -417,6 +429,10 @@ } } +#ifdef BUILD_IU + iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); +#endif + if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: redirect Iu in various places, link Iu in sgsn-test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/731 to look at the new patch set (#7). IuPS: redirect Iu in various places, link Iu in sgsn-test In gsm48_gmm_sendmsg(), redirect to iu_tx() for both cases of MM context present or not. In gsm48_rx_gmm_att_req(), compose an MM context marked as Iu for messages coming in from a ue_conn_ctx (passed in msg->dst). Also make sure cid is initialized to avoid introducing a compiler warning. In gsm48_rx_gmm_ra_upd_req(), look up an Iu MM context based on the presence of the ue_conn_ctx in msg->dst. In sgsn-test, add libiu and libasn1c, libosmo-sigtran, libosmo-ranap, which are now needed for an --enable-iu build. Change-Id: Ia47ffbfa6fa0f5a0cd76a379c57ef42faa0d80e3 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/tests/sgsn/Makefile.am 2 files changed, 65 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/31/731/7 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 4c44224..cc0caf4 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -185,8 +185,21 @@ static int gsm48_gmm_sendmsg(struct msgb *msg, int command, struct sgsn_mm_ctx *mm, bool encryptable) { - if (mm) + if (mm) { rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]); +#ifdef BUILD_IU + if (mm->ran_type == MM_CTX_T_UTRAN_Iu) + return iu_tx(msg, GPRS_SAPI_GMM); +#endif + } + +#ifdef BUILD_IU + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode + * dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (msg->dst) + return iu_tx(msg, GPRS_SAPI_GMM); +#endif /* caller needs to provide TLLI, BVCI and NSEI */ return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm, encryptable); @@ -907,7 +920,7 @@ uint32_t tmsi; char mi_string[GSM48_MI_SIZE]; struct gprs_ra_id ra_id; - uint16_t cid; + uint16_t cid = 0; enum gsm48_gmm_cause reject_cause; int rc; @@ -918,7 +931,13 @@ * with a foreign TLLI (P-TMSI that was allocated to the MS before), * or with random TLLI. */ - cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode + * dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (!msg->dst) { + /* Gb mode */ + cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); + } /* MS network capability 10.5.5.12 */ msnc_len = *cur++; @@ -972,7 +991,10 @@ #if 0 return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN); #else - ctx = sgsn_mm_ctx_alloc(0, &ra_id); + if (msg->dst) + ctx = sgsn_mm_ctx_alloc_iu(msg->dst); + else + ctx = sgsn_mm_ctx_alloc(0, &ra_id); if (!ctx) { reject_cause = GMM_CAUSE_NET_FAIL; goto rejected; @@ -995,7 +1017,10 @@ if (!ctx) { /* Allocate a context as most of our code expects one. * Context will not have an IMSI ultil ID RESP is received */ - ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id); + if (msg->dst) + ctx = sgsn_mm_ctx_alloc_iu(msg->dst); + else + ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id); ctx->p_tmsi = tmsi; } if (ctx->ran_type == MM_CTX_T_GERAN_Gb) { @@ -1272,7 +1297,31 @@ * is an optimization to avoid the RA reject (impl detached) * below, which will cause a new attach cycle. */ /* Look-up the MM context based on old RA-ID and TLLI */ - mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id); + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb + * mode dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (!msg->dst) { + mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id); + } else if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) { +#ifdef BUILD_IU + /* In Iu mode search only for ptmsi */ + char mi_string[GSM48_MI_SIZE]; + uint8_t mi_len = TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI); + uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI); + uint8_t mi_type = *mi & GSM_MI_TYPE_MASK; + uint32_t tmsi; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + + if (mi_type == GSM_MI_TYPE_TMSI) { + memcpy(&tmsi, mi+1, 4); + tmsi = ntohl(tmsi); + mmctx = sgsn_mm_ctx_by_ptmsi(tmsi); + } +#else + goto rejected; +#endif + } if (mmctx) { LOGMMCTXP(LOGL_INFO, mmctx, "Looked up by matching TLLI and P_TMSI. " diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 74af159..ce64429 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,5 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif EXTRA_DIST = sgsn_test.ok @@ -39,4 +42,11 @@ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ -lgtp -lrt +if BUILD_IU +sgsn_test_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMORANAP_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBASN1C_LIBS) +endif -- To view, visit https://gerrit.osmocom.org/731 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia47ffbfa6fa0f5a0cd76a379c57ef42faa0d80e3 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: add Iu response to create_pdp_conf() In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/732 to look at the new patch set (#7). IuPS: add Iu response to create_pdp_conf() Change-Id: Iad65ca9b77c3166d4df9a58af527e6aef7e589ee --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 3 files changed, 35 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/32/732/7 diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 28467d7..d210a35 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -30,4 +30,6 @@ time_t gprs_max_time_to_idle(void); +int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap); + #endif /* _GPRS_GMM_H */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index cc0caf4..8b8bdd1 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -2419,3 +2419,28 @@ mmctx->mm_state = GMM_REGISTERED_NORMAL; return 0; } + +#ifdef BUILD_IU +int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap) +{ + struct msgb *msg; + struct sgsn_mm_ctx *mm = pdp->mm; + struct ue_conn_ctx *uectx; + uint32_t ggsn_ip; + + uectx = mm->iu.ue_ctx; + + /* Get the IP address for ggsn user plane */ + memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l); + ggsn_ip = htonl(ggsn_ip); + + LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x," + " teid_gn=%x, use_x213_nsap=%d\n", + rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap); + + msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip, + pdp->lib->teid_gn, use_x213_nsap); + msg->l2h = msg->data; + return iu_rab_act(uectx, msg); +} +#endif diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 4a14cf6..45eff63 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -366,6 +366,14 @@ /* Activate the SNDCP layer */ sndcp_sm_activate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); return send_act_pdp_cont_acc(pctx); + } else if (pctx->mm->ran_type == MM_CTX_T_UTRAN_Iu) { +#ifdef BUILD_IU + /* Activate a radio bearer */ + iu_rab_act_ps(pdp->nsapi, pctx, 1); + return 0; +#else + return -ENOTSUP; +#endif } LOGP(DGPRS, LOGL_ERROR, "Unknown ran_type %d\n", -- To view, visit https://gerrit.osmocom.org/732 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iad65ca9b77c3166d4df9a58af527e6aef7e589ee Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: add Iu response to delete_pdp_conf() In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/733 to look at the new patch set (#7). IuPS: add Iu response to delete_pdp_conf() Change-Id: I6d601586101c0a004b2243633fab48db82b44b7c --- M openbsc/src/gprs/sgsn_libgtp.c 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/33/733/7 diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 45eff63..35d5dab 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -485,6 +485,13 @@ if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { /* Deactivate the SNDCP layer */ sndcp_sm_deactivate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); + } else { +#ifdef BUILD_IU + /* Deactivate radio bearer */ + iu_rab_deact(pctx->mm->iu.ue_ctx, 1); +#else + return -ENOTSUP; +#endif } /* Confirm deactivation of PDP context to MS */ -- To view, visit https://gerrit.osmocom.org/733 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d601586101c0a004b2243633fab48db82b44b7c Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/734 to look at the new patch set (#8). IuPS: dev hack: init hardcoded Ki on ATT REQ DEVELOPMENT HACK: Our current HLR does not support 3G authentication tokens. A new HLR/VLR implementation is being developed. Until it is ready and actual milenage authentication is properly supported, we are hardcoding a fixed Ki and use 2G auth. Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/34/734/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8b8bdd1..7d00bd5 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1039,6 +1040,34 @@ ctx->ra = ra_id; if (ctx->ran_type == MM_CTX_T_GERAN_Gb) ctx->gb.cell_id = cid; + else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) { + /* DEVELOPMENT HACK: Our current HLR does not support 3G + * authentication tokens. A new HLR/VLR implementation is being + * developed. Until it is ready and actual milenage + * authentication is properly supported, we are hardcoding a + * fixed Ki and use 2G auth. */ + unsigned char tmp_rand[16]; + /* Ki 000102030405060708090a0b0c0d0e0f */ + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1, + .u.gsm.ki = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + }; + /* XXX: Hack to make 3G auth work with special SIM card */ + ctx->auth_state = SGSN_AUTH_AUTHENTICATE; + + RAND_bytes(tmp_rand, 16); + + memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec)); + osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand); + + ctx->auth_triplet.key_seq = 0; + } + /* Update MM Context with other data */ ctx->drx_parms = drx_par; ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 1 21:44:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 21:44:49 +0000 Subject: [PATCH] openbsc[master]: IuPS: send Security Mode Command, track the new_key flag. In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/735 to look at the new patch set (#8). IuPS: send Security Mode Command, track the new_key flag. Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 2 files changed, 14 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/735/8 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 7d00bd5..14043ce 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -612,6 +612,9 @@ ctx->is_authenticated = 1; + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + ctx->iu.new_key = 1; + /* FIXME: enable LLC cipheirng */ /* Check if we can let the mobile station enter */ @@ -690,6 +693,9 @@ /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { +#ifdef BUILD_IU + int rc; +#endif #ifndef PTMSI_ALLOC struct sgsn_signal_data sig_data; #endif @@ -743,6 +749,13 @@ } /* The MS is authorized */ +#ifdef BUILD_IU + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) { + rc = iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet, 0, ctx->iu.new_key); + ctx->iu.new_key = 0; + return rc; + } +#endif switch (ctx->pending_req) { case 0: diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 19b0a1b..dd7e008 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -244,6 +244,7 @@ ctx->ran_type = MM_CTX_T_UTRAN_Iu; ctx->iu.ue_ctx = uectx; + ctx->iu.new_key = 1; ctx->mm_state = GMM_DEREGISTERED; ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0); -- To view, visit https://gerrit.osmocom.org/735 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 1 23:32:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 23:32:01 +0000 Subject: osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: Patch Set 2: If I read Holger's comment, it said "please add another test", besides stating "I wouldn't want to go without it". Instead, you have removed the TbfTest.cpp part completely; why? -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 23:33:05 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 23:33:05 +0000 Subject: osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: Patch Set 2: > said "please add another test", I mean "Could you create another test", of course... -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 23:36:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 23:36:23 +0000 Subject: osmo-pcu[master]: DL: add test case to show wrong window size In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/797 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4659494c6f93ae89e4cc4ac79fff5fcaf2d23699 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 1 23:41:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 1 Sep 2016 23:41:18 +0000 Subject: osmo-pcu[master]: Fix DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 1: Holger, is your comment ("business logic") saying the same thing as mine? i.e. that the patch duplicates a calculation that should be in a separate function called from both places. I'm afraid I don't follow on the latency/buffer bloat argument. So far I'm still expecting Arvind to un-duplicate. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 00:48:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 00:48:45 +0000 Subject: osmo-pcu[master]: EGPRS: EPDAN decoding: add test case to show no ack_nack len... In-Reply-To: References: Message-ID: Patch Set 6: > These are random values so I have kept this way. Arvind, this comment of yours is not accurate. How did you get the idea that these bits are random? I have taken a closer look now and both my suggestion to memset URBB as well as your argumentation are nonsense. Without the fix in csn1.c, 8 bits are read even though only 6 bits remain in the bit vector, leading to a read past the vector's end. But this is caught and bitvec_get_bit_pos() returns -EINVAL, which is *not* random. So your test should always expect OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); This will never end up a different byte sequence with the given input. (The only variation would be that EINVAL were defined a different value than we expect, != 22. In that case we would compose the expected bytes using the actual current -EINVAL value.) -- To view, visit https://gerrit.osmocom.org/765 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8da84794748f2e81722c3eca69b46ccc3a21552e Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:12:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:12:23 +0000 Subject: osmo-pcu[master]: EGPRS: EPDAN decoding: add test case to show no ack_nack len... In-Reply-To: References: Message-ID: Patch Set 8: Code-Review-1 Also, please explain the test name and commit summary. I see that this is about CSN1 decoding, and it seems that the "no ack_nack len" is just one particular instance where this shows. It seems a more accurate description would be: "CSN1 CSN_LEFT_ALIGNED_VAR_BMP: add test case to show attempted decoding past vector end" Would you agree, or is the case you describe as "no ack_nack len" the only case where CSN_LEFT_ALIGNED_VAR_BMP hits? I am not really familiar with CSN1 nor EPDAN -- so, do you have your facts straight? -- To view, visit https://gerrit.osmocom.org/765 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8da84794748f2e81722c3eca69b46ccc3a21552e Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:32:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:32:08 +0000 Subject: [PATCH] osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP Message-ID: Review at https://gerrit.osmocom.org/804 CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP CSN1 decoding currently contains an attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation is flawed, and in what should be the final step, 8 bits are read instead of 6 (with an extraneous read of 6 bits following after that). This leads to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Add testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp to show and expect this bug. The test's expectation shall be corrected along with the bug fix in a subsequent commit. Related: OS#1805 Tweaked-by: Neels Hofmeyr Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 --- M tests/rlcmac/RLCMACTest.cpp 1 file changed, 23 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/04/804/1 diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index 466b89e..f451dbb 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -30,6 +30,7 @@ #include "pcu_vty.h" #include #include +#include #include } using namespace std; @@ -211,6 +212,27 @@ bitvec_free(resultVector); } +void testCsnLeftAlignedVarBmpBounds() +{ + bitvec *vector = bitvec_alloc(23); + + bitvec_unhex(vector, "40200bffd161003e0e519ffffffb800000000000000000"); + RlcMacUplink_t data; + + EGPRS_AckNack_Desc_t *urbb = + &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; + memset(urbb->URBB, -1, sizeof(urbb->URBB)); + decode_gsm_rlcmac_uplink(vector, &data); + + /* + * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 + * bits should be decoded. The 13th byte should end up as 0x00, but we + * see data coming from bitvec_get_bit_pos() returning -EINVAL. + */ + OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), + "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); +} + int main(int argc, char *argv[]) { osmo_init_logging(&gprs_log_info); @@ -218,5 +240,5 @@ //printSizeofRLCMAC(); testRlcMacDownlink(); testRlcMacUplink(); - + testCsnLeftAlignedVarBmpBounds(); } -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:32:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:32:08 +0000 Subject: [PATCH] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Message-ID: Review at https://gerrit.osmocom.org/805 Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of 6. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 5 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/05/805/1 diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..99d4c3f 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { *pui8 = bitvec_read_field(vector, readIndex, nB1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f451dbb..d1d4a6e 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -221,7 +221,6 @@ EGPRS_AckNack_Desc_t *urbb = &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; - memset(urbb->URBB, -1, sizeof(urbb->URBB)); decode_gsm_rlcmac_uplink(vector, &data); /* @@ -230,7 +229,7 @@ * see data coming from bitvec_get_bit_pos() returning -EINVAL. */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:35:12 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:35:12 +0000 Subject: osmo-pcu[master]: Fix EGPRS EPDAN decoding: no ack nack dissector length In-Reply-To: References: Message-ID: Patch Set 6: I have uploaded an alternative implementation of this fix at https://gerrit.osmocom.org/805 , which I believe more clearly shows handling of 8-bit chunks with a remainder. If you agree with that implementation, we could go with that one. I would of course not have been able to fix it without your version of the fix shown here. -- To view, visit https://gerrit.osmocom.org/766 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieddf96aca82b0b0e917cfcc70aeb978799fb4e95 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:37:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:37:10 +0000 Subject: osmo-pcu[master]: EGPRS: EPDAN decoding: add test case to show no ack_nack len... In-Reply-To: References: Message-ID: Patch Set 6: I have uploaded a tweaked version of this patch at https://gerrit.osmocom.org/804 -- if you agree, we could go with that one. It is still attributed to you as author. The main differences: - the test name; - the commit log has a completely different angle; - the test expects 0xea in the 13th byte, from -EINVAL. -- To view, visit https://gerrit.osmocom.org/765 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8da84794748f2e81722c3eca69b46ccc3a21552e Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:39:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:39:34 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 1: > http://jenkins.osmocom.org/jenkins/job/osmo-pcu-gerrit/307/ : > FAILURE whoops, rebase artifact -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:39:41 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:39:41 +0000 Subject: [PATCH] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/805 to look at the new patch set (#2). Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of 6. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 6 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/05/805/2 diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..a1698a5 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f451dbb..d1d4a6e 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -221,7 +221,6 @@ EGPRS_AckNack_Desc_t *urbb = &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; - memset(urbb->URBB, -1, sizeof(urbb->URBB)); decode_gsm_rlcmac_uplink(vector, &data); /* @@ -230,7 +229,7 @@ * see data coming from bitvec_get_bit_pos() returning -EINVAL. */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:43:24 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:43:24 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 2: See also https://gerrit.osmocom.org/766 -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 01:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 01:43:33 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 1: See also https://gerrit.osmocom.org/765 -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:15:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:15:28 +0000 Subject: openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Patch Set 8: Code-Review+2 Re-adding earlier +2 vote, only commit message tweaked with respect to patch set 5. -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:16:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:16:45 +0000 Subject: [MERGED] osmo-bts[master]: common/rsl: move decision whether to chan act ack/nack to co... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: common/rsl: move decision whether to chan act ack/nack to common function ...................................................................... common/rsl: move decision whether to chan act ack/nack to common function Prepare for a dyn TS patch that needs to call rsl_tx_chan_act_ack() directly without the rel_act_kind decision. Add function rsl_tx_chan_act_acknack() to wrap rsl_tx_chan_act_ack() and rsl_tx_chan_act_nack(). Move the decision whether to drop the ack/nack, based on lchan->rel_act_kind, to the new function, losing some code dup. Change all callers to use the new function; drop the two older ones from rsl.h and make them static. Note: for nack, the exception for dyn TS in PDCH mode was missing (rsl_tx_chan_act_nack() had only the rel_act_kind != LCHAN_REL_ACT_RSL condition, but should also have had the dyn TS exception as in rsl_tx_chan_act_ack()). I already know that this exception will again be removed in an upcoming commit, but for patch readability it logically makes sense to add it here. To easily include the nack case, drop the check for which pchan the dyn TS is operating as, because a rel_act_kind == LCHAN_REL_ACT_PCU implies that it is either already in or trying to become PDCH mode. Change-Id: I57ba60c670730c6d7877a6a9b96ece0a7679a0bb --- M include/osmo-bts/rsl.h M src/common/l1sap.c M src/common/rsl.c 3 files changed, 32 insertions(+), 34 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h index 72ed2fc..093e9cb 100644 --- a/include/osmo-bts/rsl.h +++ b/include/osmo-bts/rsl.h @@ -19,8 +19,7 @@ uint8_t ra, uint8_t acc_delay); int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len); -int rsl_tx_chan_act_ack(struct gsm_lchan *lchan); -int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause); +int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_conn_fail(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan); int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7c30c9b..7eb0b62 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -455,10 +455,7 @@ lchan = get_lchan_by_chan_nr(trx, info_act_cnf->chan_nr); - if (info_act_cnf->cause) - rsl_tx_chan_act_nack(lchan, info_act_cnf->cause); - else - rsl_tx_chan_act_ack(lchan); + rsl_tx_chan_act_acknack(lchan, info_act_cnf->cause); /* During PDCH ACT, this is where we know that the PCU is done * activating a PDCH, and PDCH switchover is complete. See diff --git a/src/common/rsl.c b/src/common/rsl.c index 490ae28..8905028 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -535,26 +535,12 @@ } /* 8.4.2 sending CHANnel ACTIVation ACKnowledge */ -int rsl_tx_chan_act_ack(struct gsm_lchan *lchan) +static int rsl_tx_chan_act_ack(struct gsm_lchan *lchan) { struct gsm_time *gtime = get_time(lchan->ts->trx->bts); struct msgb *msg; uint8_t chan_nr = gsm_lchan2chan_nr(lchan); uint8_t ie[2]; - - /* - * Normally, PDCH activation via PCU does not ack back to the BSC. - * But for GSM_PCHAN_TCH_F_TCH_H_PDCH, send a non-standard act ack for - * LCHAN_REL_ACT_PCU, since the act req came from RSL initially. - */ - if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL - && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH - && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH - && lchan->rel_act_kind == LCHAN_REL_ACT_PCU)) { - LOGP(DRSL, LOGL_NOTICE, "%s not sending CHAN ACT ACK\n", - gsm_lchan_name(lchan)); - return 0; - } LOGP(DRSL, LOGL_NOTICE, "%s Tx CHAN ACT ACK\n", gsm_lchan_name(lchan)); @@ -596,16 +582,10 @@ } /* 8.4.3 sending CHANnel ACTIVation Negative ACK */ -int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause) +static int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause) { struct msgb *msg; uint8_t chan_nr = gsm_lchan2chan_nr(lchan); - - if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) { - LOGP(DRSL, LOGL_DEBUG, "%s not sending CHAN ACT NACK.\n", - gsm_lchan_name(lchan)); - return 0; - } LOGP(DRSL, LOGL_NOTICE, "%s Sending Channel Activated NACK: cause = 0x%02x\n", @@ -621,6 +601,27 @@ msg->trx = lchan->ts->trx; return abis_bts_rsl_sendmsg(msg); +} + +/* Send an RSL Channel Activation Ack if cause is zero, a Nack otherwise. */ +int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause) +{ + /* + * Normally, PDCH activation via PCU does not ack back to the BSC. + * But for GSM_PCHAN_TCH_F_TCH_H_PDCH, send a non-standard act ack for + * LCHAN_REL_ACT_PCU, since the act req came from RSL initially. + */ + if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL + && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH + && lchan->rel_act_kind == LCHAN_REL_ACT_PCU)) { + LOGP(DRSL, LOGL_NOTICE, "%s not sending CHAN ACT %s\n", + gsm_lchan_name(lchan), cause ? "NACK" : "ACK"); + return 0; + } + + if (cause) + return rsl_tx_chan_act_nack(lchan, cause); + return rsl_tx_chan_act_ack(lchan); } /* 8.4.4 sending CONNection FAILure */ @@ -782,7 +783,7 @@ LOGP(DRSL, LOGL_ERROR, "%s: error: lchan is not available, but in state: %s.\n", gsm_lchan_name(lchan), gsm_lchans_name(lchan->state)); - return rsl_tx_chan_act_nack(lchan, RSL_ERR_EQUIPMENT_FAIL); + return rsl_tx_chan_act_acknack(lchan, RSL_ERR_EQUIPMENT_FAIL); } if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) { @@ -797,8 +798,8 @@ */ rc = dyn_ts_l1_reconnect(ts, msg); if (rc) - return rsl_tx_chan_act_nack(lchan, - RSL_ERR_NORMAL_UNSPEC); + return rsl_tx_chan_act_acknack(lchan, + RSL_ERR_NORMAL_UNSPEC); /* indicate that the msgb should not be freed. */ return 1; } @@ -814,7 +815,7 @@ /* 9.3.3 Activation Type */ if (!TLVP_PRESENT(&tp, RSL_IE_ACT_TYPE)) { LOGP(DRSL, LOGL_NOTICE, "missing Activation Type\n"); - return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); + return rsl_tx_chan_act_acknack(lchan, RSL_ERR_MAND_IE_ERROR); } type = *TLVP_VAL(&tp, RSL_IE_ACT_TYPE); @@ -822,7 +823,8 @@ if (type != RSL_ACT_OSMO_PDCH) { if (!TLVP_PRESENT(&tp, RSL_IE_CHAN_MODE)) { LOGP(DRSL, LOGL_NOTICE, "missing Channel Mode\n"); - return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); + return rsl_tx_chan_act_acknack(lchan, + RSL_ERR_MAND_IE_ERROR); } cm = (struct rsl_ie_chan_mode *) TLVP_VAL(&tp, RSL_IE_CHAN_MODE); lchan_tchmode_from_cmode(lchan, cm); @@ -954,7 +956,7 @@ /* actually activate the channel in the BTS */ rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr, &tp); if (rc < 0) - return rsl_tx_chan_act_nack(lchan, -rc); + return rsl_tx_chan_act_acknack(lchan, -rc); return 0; } -- To view, visit https://gerrit.osmocom.org/747 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I57ba60c670730c6d7877a6a9b96ece0a7679a0bb Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:17:56 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:17:56 +0000 Subject: [MERGED] openbsc[master]: IuPS: add Iu response to delete_pdp_conf() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: IuPS: add Iu response to delete_pdp_conf() ...................................................................... IuPS: add Iu response to delete_pdp_conf() Change-Id: I6d601586101c0a004b2243633fab48db82b44b7c --- M openbsc/src/gprs/sgsn_libgtp.c 1 file changed, 7 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 45eff63..35d5dab 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -485,6 +485,13 @@ if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { /* Deactivate the SNDCP layer */ sndcp_sm_deactivate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); + } else { +#ifdef BUILD_IU + /* Deactivate radio bearer */ + iu_rab_deact(pctx->mm->iu.ue_ctx, 1); +#else + return -ENOTSUP; +#endif } /* Confirm deactivation of PDP context to MS */ -- To view, visit https://gerrit.osmocom.org/733 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6d601586101c0a004b2243633fab48db82b44b7c Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:17:56 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:17:56 +0000 Subject: [MERGED] openbsc[master]: IuPS: add Iu response to create_pdp_conf() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: IuPS: add Iu response to create_pdp_conf() ...................................................................... IuPS: add Iu response to create_pdp_conf() Change-Id: Iad65ca9b77c3166d4df9a58af527e6aef7e589ee --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 3 files changed, 35 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 28467d7..d210a35 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -30,4 +30,6 @@ time_t gprs_max_time_to_idle(void); +int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap); + #endif /* _GPRS_GMM_H */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index cc0caf4..8b8bdd1 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -2419,3 +2419,28 @@ mmctx->mm_state = GMM_REGISTERED_NORMAL; return 0; } + +#ifdef BUILD_IU +int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap) +{ + struct msgb *msg; + struct sgsn_mm_ctx *mm = pdp->mm; + struct ue_conn_ctx *uectx; + uint32_t ggsn_ip; + + uectx = mm->iu.ue_ctx; + + /* Get the IP address for ggsn user plane */ + memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l); + ggsn_ip = htonl(ggsn_ip); + + LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x," + " teid_gn=%x, use_x213_nsap=%d\n", + rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap); + + msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip, + pdp->lib->teid_gn, use_x213_nsap); + msg->l2h = msg->data; + return iu_rab_act(uectx, msg); +} +#endif diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 4a14cf6..45eff63 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -366,6 +366,14 @@ /* Activate the SNDCP layer */ sndcp_sm_activate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); return send_act_pdp_cont_acc(pctx); + } else if (pctx->mm->ran_type == MM_CTX_T_UTRAN_Iu) { +#ifdef BUILD_IU + /* Activate a radio bearer */ + iu_rab_act_ps(pdp->nsapi, pctx, 1); + return 0; +#else + return -ENOTSUP; +#endif } LOGP(DGPRS, LOGL_ERROR, "Unknown ran_type %d\n", -- To view, visit https://gerrit.osmocom.org/732 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iad65ca9b77c3166d4df9a58af527e6aef7e589ee Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:17:56 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:17:56 +0000 Subject: [MERGED] openbsc[master]: IuPS: redirect Iu in various places, link Iu in sgsn-test In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: IuPS: redirect Iu in various places, link Iu in sgsn-test ...................................................................... IuPS: redirect Iu in various places, link Iu in sgsn-test In gsm48_gmm_sendmsg(), redirect to iu_tx() for both cases of MM context present or not. In gsm48_rx_gmm_att_req(), compose an MM context marked as Iu for messages coming in from a ue_conn_ctx (passed in msg->dst). Also make sure cid is initialized to avoid introducing a compiler warning. In gsm48_rx_gmm_ra_upd_req(), look up an Iu MM context based on the presence of the ue_conn_ctx in msg->dst. In sgsn-test, add libiu and libasn1c, libosmo-sigtran, libosmo-ranap, which are now needed for an --enable-iu build. Change-Id: Ia47ffbfa6fa0f5a0cd76a379c57ef42faa0d80e3 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/tests/sgsn/Makefile.am 2 files changed, 65 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 4c44224..cc0caf4 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -185,8 +185,21 @@ static int gsm48_gmm_sendmsg(struct msgb *msg, int command, struct sgsn_mm_ctx *mm, bool encryptable) { - if (mm) + if (mm) { rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]); +#ifdef BUILD_IU + if (mm->ran_type == MM_CTX_T_UTRAN_Iu) + return iu_tx(msg, GPRS_SAPI_GMM); +#endif + } + +#ifdef BUILD_IU + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode + * dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (msg->dst) + return iu_tx(msg, GPRS_SAPI_GMM); +#endif /* caller needs to provide TLLI, BVCI and NSEI */ return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm, encryptable); @@ -907,7 +920,7 @@ uint32_t tmsi; char mi_string[GSM48_MI_SIZE]; struct gprs_ra_id ra_id; - uint16_t cid; + uint16_t cid = 0; enum gsm48_gmm_cause reject_cause; int rc; @@ -918,7 +931,13 @@ * with a foreign TLLI (P-TMSI that was allocated to the MS before), * or with random TLLI. */ - cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode + * dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (!msg->dst) { + /* Gb mode */ + cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); + } /* MS network capability 10.5.5.12 */ msnc_len = *cur++; @@ -972,7 +991,10 @@ #if 0 return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN); #else - ctx = sgsn_mm_ctx_alloc(0, &ra_id); + if (msg->dst) + ctx = sgsn_mm_ctx_alloc_iu(msg->dst); + else + ctx = sgsn_mm_ctx_alloc(0, &ra_id); if (!ctx) { reject_cause = GMM_CAUSE_NET_FAIL; goto rejected; @@ -995,7 +1017,10 @@ if (!ctx) { /* Allocate a context as most of our code expects one. * Context will not have an IMSI ultil ID RESP is received */ - ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id); + if (msg->dst) + ctx = sgsn_mm_ctx_alloc_iu(msg->dst); + else + ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id); ctx->p_tmsi = tmsi; } if (ctx->ran_type == MM_CTX_T_GERAN_Gb) { @@ -1272,7 +1297,31 @@ * is an optimization to avoid the RA reject (impl detached) * below, which will cause a new attach cycle. */ /* Look-up the MM context based on old RA-ID and TLLI */ - mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id); + /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb + * mode dst is empty. */ + /* FIXME: have a more explicit indicator for Iu messages */ + if (!msg->dst) { + mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id); + } else if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) { +#ifdef BUILD_IU + /* In Iu mode search only for ptmsi */ + char mi_string[GSM48_MI_SIZE]; + uint8_t mi_len = TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI); + uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI); + uint8_t mi_type = *mi & GSM_MI_TYPE_MASK; + uint32_t tmsi; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + + if (mi_type == GSM_MI_TYPE_TMSI) { + memcpy(&tmsi, mi+1, 4); + tmsi = ntohl(tmsi); + mmctx = sgsn_mm_ctx_by_ptmsi(tmsi); + } +#else + goto rejected; +#endif + } if (mmctx) { LOGMMCTXP(LOGL_INFO, mmctx, "Looked up by matching TLLI and P_TMSI. " diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 74af159..ce64429 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,5 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif EXTRA_DIST = sgsn_test.ok @@ -39,4 +42,11 @@ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ -lgtp -lrt +if BUILD_IU +sgsn_test_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMORANAP_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBASN1C_LIBS) +endif -- To view, visit https://gerrit.osmocom.org/731 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia47ffbfa6fa0f5a0cd76a379c57ef42faa0d80e3 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:17:56 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:17:56 +0000 Subject: [MERGED] openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: IuPS: osmo-sgsn: add core IuPS impl, call iu_init() ...................................................................... IuPS: osmo-sgsn: add core IuPS impl, call iu_init() Add main Iu entry points for IuPS: * gsm0408_gprs_rcvmsg_iu() * sgsn_ranap_iu_event() * sgsn_ranap_rab_ass_resp() Add main MM context management for IuPS: * sgsn_mm_ctx_by_ue_ctx() * sgsn_mm_ctx_alloc_iu() Call iu_init() from sgsn_main.c. Add asn_debug impl ("extern" from libasn1c). Initialize asn_debug VTY command (iu_vty_init()). osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 --- M openbsc/include/openbsc/gprs_gmm.h M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_main.c 7 files changed, 239 insertions(+), 3 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 8a3ffea..28467d7 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -14,6 +14,8 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable); +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, struct gprs_llc_llme *llme); diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index b0dd75f..18cbab8 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -226,6 +226,7 @@ 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, @@ -234,6 +235,8 @@ /* Allocate a new SGSN MM context */ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, const struct gprs_ra_id *raid); +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, diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 1b6de46..6a95315 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -3,6 +3,10 @@ $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \ $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +if BUILD_IU +AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +endif + OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) @@ -28,9 +32,15 @@ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ + $(top_builddir)/src/libcommon/libcommon.a +if BUILD_IU +osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a +endif +osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) -lrt +if BUILD_IU +osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +endif osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \ gtphub_vty.c sgsn_ares.c gprs_utils.c diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 1efada9..4c44224 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -33,6 +33,8 @@ #include +#include "bscconfig.h" + #include #include #include @@ -44,6 +46,10 @@ #include #include + +#ifdef BUILD_IU +#include +#endif #include #include @@ -57,6 +63,10 @@ #include #include #include + +#ifdef BUILD_IU +#include +#endif #include @@ -96,6 +106,45 @@ }; static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); + +#ifdef BUILD_IU +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) +{ + struct sgsn_mm_ctx *mm; + int rc = -1; + + mm = sgsn_mm_ctx_by_ue_ctx(ctx); + if (!mm) { + LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type); + return rc; + } + + switch (type) { + case IU_EVENT_RAB_ASSIGN: + rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); + break; + case IU_EVENT_IU_RELEASE: + /* fall thru */ + case IU_EVENT_LINK_INVALIDATED: + /* Clean up ue_conn_ctx here */ + LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + rc = 0; + break; + case IU_EVENT_SECURITY_MODE_COMPLETE: + /* Continue authentication here */ + mm->iu.ue_ctx->integrity_active = 1; + rc = gsm48_gmm_authorize(mm); + break; + default: + LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); + rc = -1; + break; + } + return rc; +} +#endif + /* Our implementation, should be kept in SGSN */ @@ -2193,6 +2242,45 @@ return rc; } +/* Main entry point for incoming 04.08 GPRS messages from Iu */ +int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, + uint16_t *sai) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t pdisc = gsm48_hdr_pdisc(gh); + struct sgsn_mm_ctx *mmctx; + int rc = -EINVAL; + + mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst); + if (mmctx) { + rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); + if (ra_id) + memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra)); + } + + /* MMCTX can be NULL */ + + switch (pdisc) { + case GSM48_PDISC_MM_GPRS: + rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false); +#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?" + break; + case GSM48_PDISC_SM_GPRS: + rc = gsm0408_rcv_gsm(mmctx, msg, NULL); + break; + default: + LOGMMCTXP(LOGL_NOTICE, mmctx, + "Unknown GSM 04.08 discriminator 0x%02x: %s\n", + pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); + /* FIXME: return status message */ + break; + } + + /* MMCTX can be invalid */ + + return rc; +} + /* Main entry point for incoming 04.08 GPRS messages from Gb */ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, bool drop_cipherable) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 9cd992b..19b0a1b 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -39,6 +39,7 @@ #include #include #include "openbsc/gprs_llc.h" +#include #include @@ -130,6 +131,20 @@ sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0); } +/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx) +{ + struct sgsn_mm_ctx *ctx; + + 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 */ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, const struct gprs_ra_id *raid) @@ -218,6 +233,32 @@ 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->mm_state = GMM_DEREGISTERED; + 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! */ static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..4a14cf6 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -34,6 +34,8 @@ #include #include +#include "bscconfig.h" + #include #include #include @@ -47,6 +49,11 @@ #include #include #include + +#ifdef BUILD_IU +#include +#include +#endif #include #include @@ -218,7 +225,10 @@ memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - /* SGSN address for user plane */ + /* SGSN address for user plane + * Default to the control plane addr for now. If we are connected to a + * hnbgw via IuPS we'll need to send a PDP context update with the + * correct IP address after the RAB Assignment is complete */ pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr, sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); @@ -383,6 +393,72 @@ return EOF; } +#ifdef BUILD_IU +/* Callback for RAB assignment response */ +int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) +{ + uint8_t rab_id; + bool require_pdp_update = false; + struct sgsn_pdp_ctx *pdp = NULL; + RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; + + rab_id = item->rAB_ID.buf[0]; + + pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id); + if (!pdp) { + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id); + return -1; + } + + if (item->transportLayerAddress) { + LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf, + item->transportLayerAddress->size)); + switch (item->transportLayerAddress->size) { + case 7: + /* It must be IPv4 inside a X213 NSAP */ + memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4); + break; + case 4: + /* It must be a raw IPv4 address */ + memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4); + break; + case 16: + /* TODO: It must be a raw IPv6 address */ + case 19: + /* TODO: It must be IPv6 inside a X213 NSAP */ + default: + LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown " + "transport layer address size %u\n", + item->transportLayerAddress->size); + return -1; + } + require_pdp_update = true; + } + + /* The TEI on the RNC side might have changed, too */ + if (item->iuTransportAssociation && + item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI && + item->iuTransportAssociation->choice.gTP_TEI.buf && + item->iuTransportAssociation->choice.gTP_TEI.size >= 4) { + uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf); + LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n", + pdp->lib->teid_own, tei); + pdp->lib->teid_own = tei; + require_pdp_update = true; + } + + if (require_pdp_update) + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); + + if (pdp->state != PDP_STATE_CR_CONF) { + send_act_pdp_cont_acc(pdp); + pdp->state = PDP_STATE_CR_CONF; + } + return 0; + +} +#endif + /* Confirmation of a PDP Context Delete */ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..7d533c0 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -56,6 +56,8 @@ #include #include #include +#include + #include #include @@ -300,6 +302,13 @@ .num_cat = ARRAY_SIZE(gprs_categories), }; +/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1 + * binary code decoded and encoded during Iu communication should be logged to + * stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)": + * http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */ +int asn_debug = 0; + +int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data); int main(int argc, char **argv) { @@ -326,6 +335,9 @@ osmo_stats_vty_add_cmds(&gprs_log_info); sgsn_vty_init(); ctrl_vty_init(tall_bsc_ctx); +#ifdef BUILD_IU + iu_vty_init(&asn_debug); +#endif handle_options(argc, argv); @@ -417,6 +429,10 @@ } } +#ifdef BUILD_IU + iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); +#endif + if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/729 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:21:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:21:42 +0000 Subject: [PATCH] osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/804 to look at the new patch set (#2). CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP CSN1 decoding currently contains an attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation is flawed, and in what should be the final step, 8 bits are read instead of 6 (with an extraneous read of 6 bits following after that). This leads to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Add testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp to show and expect this bug. The test's expectation shall be corrected along with the bug fix in a subsequent commit. Related: OS#1805 Tweaked-by: Neels Hofmeyr Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 --- M tests/rlcmac/RLCMACTest.cpp 1 file changed, 22 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/04/804/2 diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index 466b89e..f633dd8 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -30,6 +30,7 @@ #include "pcu_vty.h" #include #include +#include #include } using namespace std; @@ -211,6 +212,26 @@ bitvec_free(resultVector); } +void testCsnLeftAlignedVarBmpBounds() +{ + bitvec *vector = bitvec_alloc(23); + + bitvec_unhex(vector, "40200bffd161003e0e519ffffffb800000000000000000"); + RlcMacUplink_t data; + + EGPRS_AckNack_Desc_t *urbb = + &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; + decode_gsm_rlcmac_uplink(vector, &data); + + /* + * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 + * bits should be decoded. The 13th byte should end up as 0x00, but we + * see data coming from bitvec_get_bit_pos() returning -EINVAL. + */ + OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), + "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); +} + int main(int argc, char *argv[]) { osmo_init_logging(&gprs_log_info); @@ -218,5 +239,5 @@ //printSizeofRLCMAC(); testRlcMacDownlink(); testRlcMacUplink(); - + testCsnLeftAlignedVarBmpBounds(); } -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:21:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:21:42 +0000 Subject: [PATCH] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/805 to look at the new patch set (#3). Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of 6. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 6 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/05/805/3 diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..a1698a5 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f633dd8..d1d4a6e 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -229,7 +229,7 @@ * see data coming from bitvec_get_bit_pos() returning -EINVAL. */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: add GMM Service Request rx and tx In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/737 to look at the new patch set (#9). IuPS: add GMM Service Request rx and tx Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 199 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/37/737/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 14043ce..b515abd 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -690,6 +690,75 @@ strncpy(&ctx->hlr[0], called.number, sizeof(ctx->hlr) - 1); } +#ifdef BUILD_IU +/* Chapter 9.4.21: Service accept */ +static int gsm48_tx_gmm_service_ack(struct sgsn_mm_ctx *mm) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE ACK"); + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_INFO, mm, "<- GPRS SERVICE ACCEPT (P-TMSI=0x%08x)\n", mm->p_tmsi); + + mmctx2msgid(msg, mm); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_ACK; + + /* Optional: PDP context status */ + /* Optional: MBMS context status */ + + return gsm48_gmm_sendmsg(msg, 0, mm, false); +} +#endif + +/* Chapter 9.4.22: Service reject */ +static int _tx_gmm_service_rej(struct msgb *msg, uint8_t gmm_cause, + const struct sgsn_mm_ctx *mm) +{ + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS SERVICE REJECT: %s\n", + get_value_string(gsm48_gmm_cause_names, gmm_cause)); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_REJ; + gh->data[0] = gmm_cause; + + return gsm48_gmm_sendmsg(msg, 0, NULL, true); +} +static int gsm48_tx_gmm_service_rej_oldmsg(const struct msgb *old_msg, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ OLD"); + gmm_copy_id(msg, old_msg); + return _tx_gmm_service_rej(msg, gmm_cause, NULL); +} +#if 0 +-- currently unused -- +static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ"); + mmctx2msgid(msg, mm); + return _tx_gmm_service_rej(msg, gmm_cause, mm); +} +#endif + +static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm); + +#ifdef BUILD_IU +void activate_pdp_rabs(struct sgsn_mm_ctx *ctx) +{ + /* Send RAB activation requests for all PDP contexts */ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &ctx->pdp_list, list) { + iu_rab_act_ps(pdp->nsapi, pdp, 1); + } +} +#endif + /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { @@ -778,6 +847,23 @@ #endif return gsm48_tx_gmm_att_ack(ctx); +#ifdef BUILD_IU + case GSM48_MT_GMM_SERVICE_REQ: + /* TODO: PMM State transition */ + ctx->pending_req = 0; + rc = gsm48_tx_gmm_service_ack(ctx); + + if (ctx->iu.service.type == 1) { + activate_pdp_rabs(ctx); + } + + return rc; +#endif + case GSM48_MT_GMM_RA_UPD_REQ: + ctx->pending_req = 0; + /* Send RA UPDATE ACCEPT */ + return gsm48_tx_gmm_ra_upd_ack(ctx); + default: LOGMMCTXP(LOGL_ERROR, ctx, "only Attach Request is supported yet, " @@ -1473,6 +1559,116 @@ return rc; } +/* 3GPP TS 24.008 Section 9.4.20 Service request. + * In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back + * to PMM-CONNECTED mode. */ +static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t *cur = gh->data, *mi; + uint8_t ciph_seq_nr, service_type, mi_len, mi_type; + uint32_t tmsi; + struct tlv_parsed tp; + char mi_string[GSM48_MI_SIZE]; + enum gsm48_gmm_cause reject_cause; + int rc; + + LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST "); + + /* This message is only valid in Iu mode */ + if (!msg->dst) { + LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n"); + return -1; + } + + /* Skip Ciphering key sequence number 10.5.1.2 */ + ciph_seq_nr = *cur & 0x07; + + /* Service type 10.5.5.20 */ + service_type = (*cur++ >> 4) & 0x07; + + /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ + mi_len = *cur++; + mi = cur; + if (mi_len > 8) + goto err_inval; + mi_type = *mi & GSM_MI_TYPE_MASK; + cur += mi_len; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + + DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string, + get_value_string(gprs_service_t_strs, service_type)); + + LOGPC(DMM, LOGL_INFO, "\n"); + + /* Optional: PDP context status, MBMS context status, Uplink data status, Device properties */ + tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, (msg->data + msg->len) - cur, 0, 0); + + switch (mi_type) { + case GSM_MI_TYPE_IMSI: + /* Try to find MM context based on IMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_imsi(mi_string); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + case GSM_MI_TYPE_TMSI: + memcpy(&tmsi, mi+1, 4); + tmsi = ntohl(tmsi); + /* Try to find MM context based on P-TMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_ptmsi(tmsi); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + default: + LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting SERVICE REQUEST with " + "MI type %s\n", gsm48_mi_type_name(mi_type)); + reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; + goto rejected; + } + + ctx->mm_state = GMM_COMMON_PROC_INIT; + + ctx->iu.service.type = service_type; + + /* TODO: Handle those only in case of accept? */ + /* Look at PDP Context Status IE and see if MS's view of + * activated/deactivated NSAPIs agrees with our view */ + if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) { + const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS); + process_ms_ctx_status(ctx, pdp_status); + } + + + ctx->pending_req = GSM48_MT_GMM_SERVICE_REQ; + return gsm48_gmm_authorize(ctx); + +err_inval: + LOGPC(DMM, LOGL_INFO, "\n"); + reject_cause = GMM_CAUSE_SEM_INCORR_MSG; + +rejected: + /* Send SERVICE REJECT */ + LOGMMCTXP(LOGL_NOTICE, ctx, + "Rejecting Service Request with cause '%s' (%d)\n", + get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); + rc = gsm48_tx_gmm_service_rej_oldmsg(msg, reject_cause); + + return rc; + +} + + static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); @@ -1551,6 +1747,9 @@ case GSM48_MT_GMM_ATTACH_REQ: rc = gsm48_rx_gmm_att_req(mmctx, msg, llme); break; + case GSM48_MT_GMM_SERVICE_REQ: + rc = gsm48_rx_gmm_service_req(mmctx, msg); + break; /* For all the following types mmctx can not be NULL */ case GSM48_MT_GMM_ID_RESP: if (!mmctx) -- To view, visit https://gerrit.osmocom.org/737 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: RA UPD: make sure to authorize, for Iu Integrity Prote... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/738 to look at the new patch set (#9). IuPS: RA UPD: make sure to authorize, for Iu Integrity Protection Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 7 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/738/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index b515abd..53b6322 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -50,6 +50,7 @@ #ifdef BUILD_IU #include +#include #endif #include @@ -853,9 +854,8 @@ ctx->pending_req = 0; rc = gsm48_tx_gmm_service_ack(ctx); - if (ctx->iu.service.type == 1) { + if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) activate_pdp_rabs(ctx); - } return rc; #endif @@ -1540,8 +1540,11 @@ process_ms_ctx_status(mmctx, pdp_status); } - /* Send RA UPDATE ACCEPT */ - return gsm48_tx_gmm_ra_upd_ack(mmctx); + /* Send RA UPDATE ACCEPT. In Iu, the RA upd request can be called from + * a new Iu connection, so we might need to re-authenticate the + * connection as well as turn on integrity protection. */ + mmctx->pending_req = GSM48_MT_GMM_RA_UPD_REQ; + return gsm48_gmm_authorize(mmctx); rejected: /* Send RA UPDATE REJECT */ -- To view, visit https://gerrit.osmocom.org/738 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM ... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/739 to look at the new patch set (#9). IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM state Iu needs to page to transfer data in PMM-IDLE state. Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 --- M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 3 files changed, 18 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/739/9 diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 18cbab8..24e286c 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -31,6 +31,16 @@ 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, @@ -117,6 +127,7 @@ char imsi[GSM23003_IMSI_MAX_DIGITS+1]; enum gprs_gmm_state mm_state; + enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ uint32_t p_tmsi; uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ uint32_t p_tmsi_sig; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 53b6322..99e4a8c 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -131,6 +131,8 @@ case IU_EVENT_LINK_INVALIDATED: /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + if (mm->pmm_state == PMM_CONNECTED) + mm->pmm_state = PMM_IDLE; rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -241,6 +243,7 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; + ctx->pmm_state = PMM_DETACHED; sgsn_mm_ctx_cleanup_free(ctx); } @@ -852,6 +855,7 @@ case GSM48_MT_GMM_SERVICE_REQ: /* TODO: PMM State transition */ ctx->pending_req = 0; + ctx->pmm_state = PMM_CONNECTED; rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1793,6 +1797,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1815,6 +1820,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index dd7e008..e5a54d9 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -246,6 +246,7 @@ 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); -- To view, visit https://gerrit.osmocom.org/739 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: GMM Attach: reset MM ctx pending_req In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/740 to look at the new patch set (#9). IuPS: GMM Attach: reset MM ctx pending_req Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/40/740/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 99e4a8c..c17d813 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -836,6 +836,7 @@ "no pending request, authorization completed\n"); break; case GSM48_MT_GMM_ATTACH_REQ: + ctx->pending_req = 0; extract_subscr_msisdn(ctx); extract_subscr_hlr(ctx); -- To view, visit https://gerrit.osmocom.org/740 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: Introduce function to change PMM state In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/741 to look at the new patch set (#9). IuPS: Introduce function to change PMM state This is where IuPS will redirect GTP-U endpoints in a subsequent commit. Also add comprehensive logging of pmm_state transitions. Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/41/741/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index c17d813..cb3d4ee 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,29 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) +{ + if (ctx->pmm_state == state) + return; + + LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %i to %i\n", ctx->pmm_state, state); + + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + { + switch (state) { + case PMM_IDLE: + /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + break; + case PMM_CONNECTED: + break; + default: + break; + } + } + + ctx->pmm_state = state; +} + #ifdef BUILD_IU int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) @@ -132,7 +155,7 @@ /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); if (mm->pmm_state == PMM_CONNECTED) - mm->pmm_state = PMM_IDLE; + mmctx_set_pmm_state(mm, PMM_IDLE); rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -243,7 +266,8 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; - ctx->pmm_state = PMM_DETACHED; + + mmctx_set_pmm_state(ctx, PMM_DETACHED); sgsn_mm_ctx_cleanup_free(ctx); } @@ -854,9 +878,8 @@ return gsm48_tx_gmm_att_ack(ctx); #ifdef BUILD_IU case GSM48_MT_GMM_SERVICE_REQ: - /* TODO: PMM State transition */ ctx->pending_req = 0; - ctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(ctx, PMM_CONNECTED); rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1798,7 +1821,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1821,7 +1844,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); -- To view, visit https://gerrit.osmocom.org/741 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE ... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/742 to look at the new patch set (#9). IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE when data arrives Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b --- M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 3 files changed, 32 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/742/9 diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..22809b7 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -138,6 +138,7 @@ uint16_t nsapi, struct tlv_parsed *tp); int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); /* gprs_sndcp.c */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index cb3d4ee..3d74647 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,16 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx) +{ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) { + sgsn_pdp_upd_gtp_u(pdp, + &sgsn->cfg.gtp_listenaddr.sin_addr, + sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); + } +} + void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) { if (ctx->pmm_state == state) @@ -120,7 +130,8 @@ { switch (state) { case PMM_IDLE: - /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + /* TODO: start RA Upd timer */ + mmctx_change_gtpu_endpoints_to_sgsn(ctx); break; case PMM_CONNECTED: break; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 35d5dab..04bd40a 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -401,6 +401,13 @@ return EOF; } +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen) +{ + pdp->lib->gsnlu.l = alen; + memcpy(pdp->lib->gsnlu.v, addr, alen); + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); +} + #ifdef BUILD_IU /* Callback for RAB assignment response */ int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) @@ -621,6 +628,18 @@ return -EIO; } + if (mm->ran_type == MM_CTX_T_UTRAN_Iu) { +#ifdef BUILD_IU + /* Ignore the packet for now and page the UE to get the RAB + * reestablished */ + iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac, mm->ra.rac); + + return 0; +#else + return -ENOTSUP; +#endif + } + msg = msgb_alloc_headroom(len+256, 128, "GTP->SNDCP"); ud = msgb_put(msg, len); memcpy(ud, packet, len); -- To view, visit https://gerrit.osmocom.org/742 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/734 to look at the new patch set (#9). IuPS: dev hack: init hardcoded Ki on ATT REQ DEVELOPMENT HACK: Our current HLR does not support 3G authentication tokens. A new HLR/VLR implementation is being developed. Until it is ready and actual milenage authentication is properly supported, we are hardcoding a fixed Ki and use 2G auth. Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/34/734/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8b8bdd1..7d00bd5 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1039,6 +1040,34 @@ ctx->ra = ra_id; if (ctx->ran_type == MM_CTX_T_GERAN_Gb) ctx->gb.cell_id = cid; + else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) { + /* DEVELOPMENT HACK: Our current HLR does not support 3G + * authentication tokens. A new HLR/VLR implementation is being + * developed. Until it is ready and actual milenage + * authentication is properly supported, we are hardcoding a + * fixed Ki and use 2G auth. */ + unsigned char tmp_rand[16]; + /* Ki 000102030405060708090a0b0c0d0e0f */ + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1, + .u.gsm.ki = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + }; + /* XXX: Hack to make 3G auth work with special SIM card */ + ctx->auth_state = SGSN_AUTH_AUTHENTICATE; + + RAND_bytes(tmp_rand, 16); + + memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec)); + osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand); + + ctx->auth_triplet.key_seq = 0; + } + /* Update MM Context with other data */ ctx->drx_parms = drx_par; ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:29:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:29:47 +0000 Subject: [PATCH] openbsc[master]: IuPS: send Security Mode Command, track the new_key flag. In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/735 to look at the new patch set (#9). IuPS: send Security Mode Command, track the new_key flag. Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 2 files changed, 14 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/735/9 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 7d00bd5..14043ce 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -612,6 +612,9 @@ ctx->is_authenticated = 1; + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + ctx->iu.new_key = 1; + /* FIXME: enable LLC cipheirng */ /* Check if we can let the mobile station enter */ @@ -690,6 +693,9 @@ /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { +#ifdef BUILD_IU + int rc; +#endif #ifndef PTMSI_ALLOC struct sgsn_signal_data sig_data; #endif @@ -743,6 +749,13 @@ } /* The MS is authorized */ +#ifdef BUILD_IU + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) { + rc = iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet, 0, ctx->iu.new_key); + ctx->iu.new_key = 0; + return rc; + } +#endif switch (ctx->pending_req) { case 0: diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 19b0a1b..dd7e008 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -244,6 +244,7 @@ ctx->ran_type = MM_CTX_T_UTRAN_Iu; ctx->iu.ue_ctx = uectx; + ctx->iu.new_key = 1; ctx->mm_state = GMM_DEREGISTERED; ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0); -- To view, visit https://gerrit.osmocom.org/735 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:40:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:40:04 +0000 Subject: [PATCH] osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/804 to look at the new patch set (#3). CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP CSN1 decoding currently contains an attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation is flawed, and in what should be the final step of reading n < 8 bits, 8 bits are read instead of n (with an extraneous read of n bits following after that). This leads to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Add testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp to show and expect this bug. The test's expectation shall be corrected along with the bug fix in a subsequent commit. Related: OS#1805 Tweaked-by: Neels Hofmeyr Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 --- M tests/rlcmac/RLCMACTest.cpp 1 file changed, 22 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/04/804/3 diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index 466b89e..f633dd8 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -30,6 +30,7 @@ #include "pcu_vty.h" #include #include +#include #include } using namespace std; @@ -211,6 +212,26 @@ bitvec_free(resultVector); } +void testCsnLeftAlignedVarBmpBounds() +{ + bitvec *vector = bitvec_alloc(23); + + bitvec_unhex(vector, "40200bffd161003e0e519ffffffb800000000000000000"); + RlcMacUplink_t data; + + EGPRS_AckNack_Desc_t *urbb = + &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; + decode_gsm_rlcmac_uplink(vector, &data); + + /* + * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 + * bits should be decoded. The 13th byte should end up as 0x00, but we + * see data coming from bitvec_get_bit_pos() returning -EINVAL. + */ + OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), + "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); +} + int main(int argc, char *argv[]) { osmo_init_logging(&gprs_log_info); @@ -218,5 +239,5 @@ //printSizeofRLCMAC(); testRlcMacDownlink(); testRlcMacUplink(); - + testCsnLeftAlignedVarBmpBounds(); } -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:40:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:40:04 +0000 Subject: [PATCH] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/805 to look at the new patch set (#4). Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of the remainder < 8. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 6 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/05/805/4 diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..a1698a5 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f633dd8..d1d4a6e 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -229,7 +229,7 @@ * see data coming from bitvec_get_bit_pos() returning -EINVAL. */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:42:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 2 Sep 2016 02:42:33 +0000 Subject: [PATCH] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/805 to look at the new patch set (#5). Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of the remainder < 8. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 6 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/05/805/5 diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..a1698a5 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f633dd8..97e5e60 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -223,13 +223,8 @@ &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; decode_gsm_rlcmac_uplink(vector, &data); - /* - * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 - * bits should be decoded. The 13th byte should end up as 0x00, but we - * see data coming from bitvec_get_bit_pos() returning -EINVAL. - */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:44:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 02:44:40 +0000 Subject: [MERGED] osmo-pcu[master]: DL: add test case to show wrong window size In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: DL: add test case to show wrong window size ...................................................................... DL: add test case to show wrong window size This patch adds a test case test_tbf_update_ws. Which expects a current bug with DL window size calculation. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1808 Change-Id: I4659494c6f93ae89e4cc4ac79fff5fcaf2d23699 --- M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 3 files changed, 111 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index a4de6c9..ca5a3c8 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1774,6 +1774,65 @@ gprs_bssgp_destroy(); } +static void test_tbf_update_ws(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + uint8_t ms_class = 11; + gprs_rlcmac_dl_tbf *dl_tbf; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + setup_bts(&the_bts, ts_no); + + bts->ws_base = 128; + bts->ws_pdch = 64; + bts->alloc_algorithm = alloc_algorithm_b; + bts->trx[0].pdch[2].enable(); + bts->trx[0].pdch[3].enable(); + bts->trx[0].pdch[4].enable(); + bts->trx[0].pdch[5].enable(); + + gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, + 1234, 1234, 1234, 1, 1, 0, 0, 0); + + /* EGPRS-only */ + bts->egprs_enabled = 1; + + /* Does support EGPRS */ + dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 1); + + OSMO_ASSERT(dl_tbf != NULL); + fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", + dl_tbf->dl_slots(), + pcu_bitcount(dl_tbf->dl_slots()), + dl_tbf->window()->ws()); + OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 1); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + + dl_tbf->update(); + + /* + * TODO: Should not expect window size as 192. + * should be fixed in subsequent patch + */ + OSMO_ASSERT(dl_tbf != NULL); + fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", + dl_tbf->dl_slots(), + pcu_bitcount(dl_tbf->dl_slots()), + dl_tbf->window()->ws()); + OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + + tbf_free(dl_tbf); + + printf("=== end %s ===\n", __func__); + + gprs_bssgp_destroy(); +} + static void test_tbf_puan_urbb_len(void) { BTS the_bts; @@ -2485,6 +2544,7 @@ test_tbf_egprs_retx_dl(); test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); + test_tbf_update_ws(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 452f1c1..67aade9 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6335,3 +6335,52 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Slot Allocation (Algorithm B) for class 11 +- Rx=4 Tx=3 Sum Rx+Tx=5 Tta=3 Ttb=1 Tra=2 Trb=1 Type=1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Possible DL/UL slots: (TS=0)"..CCCC.."(TS=7) +- Selected DL slots: (TS=0)"..ddDd.."(TS=7), single +Using single slot at TS 4 for DL +- Reserved DL/UL slots: (TS=0)"....C..."(TS=7) +- Assigning DL TS 4 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 192 +DL TBF slots: 0x10, N: 1, WS: 192 +********** TBF update ********** +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +- Selected DL slots: (TS=0)"..DDDD.."(TS=7) +Using 4 slots for DL +- Assigning DL TS 2 +PDCH(TS 2, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 3 +PDCH(TS 3, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 4 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 5 +PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free +PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0x00000000 +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index dda72ef..13ad362 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -62,3 +62,5 @@ === end test_tbf_egprs_spb_dl === === start test_tbf_puan_urbb_len === === end test_tbf_puan_urbb_len === +=== start test_tbf_update_ws === +=== end test_tbf_update_ws === -- To view, visit https://gerrit.osmocom.org/797 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4659494c6f93ae89e4cc4ac79fff5fcaf2d23699 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:48:54 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 02:48:54 +0000 Subject: osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: Patch Set 2: Hi Neels, I was thinking about keeping the old test. But soon realized both are solving the same purpose. What I mean is both are identical test cases. More over the issue was related to window management. So I have removed the test. It is better we wait for Holger to comment on this. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:50:20 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 02:50:20 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 02:50:38 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 02:50:38 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 06:30:47 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 2 Sep 2016 06:30:47 +0000 Subject: osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 I would have kept your original tbf test. It goes through a lot more layers and might be able to catch other regressions because it involves much more code. Now that it is gone, I will not ask for it to be re-added. You have found a window handling issue, we have a very specific test for it and soon a fix -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 06:31:13 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 2 Sep 2016 06:31:13 +0000 Subject: osmo-pcu[master]: Fix GPRS PUAN encoding: wrong BSN status In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/771 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I98e586aa5cb9200cf03e092556304211d4d459aa Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 06:45:33 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 06:45:33 +0000 Subject: [MERGED] osmo-pcu[master]: GPRS: PUAN encoding: add test case to show wrong BSNs status In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: GPRS: PUAN encoding: add test case to show wrong BSNs status ...................................................................... GPRS: PUAN encoding: add test case to show wrong BSNs status This patch adds a test case which expects a current bug with GPRS PUAN encoding. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1806 Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 --- M tests/types/TypesTest.cpp 1 file changed, 18 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp index c56b125..c5654f6 100644 --- a/tests/types/TypesTest.cpp +++ b/tests/types/TypesTest.cpp @@ -322,6 +322,24 @@ ul_win.receive_bsn(4); count = ul_win.raise_v_q(); OSMO_ASSERT(count == 0); + + /* + * SSN wrap around case + * TODO: Should not expect any BSN as nacked. + * should be fixed in subsequent patch + */ + rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR"; + for (int i = 0; i < 128; ++i) { + ul_win.receive_bsn(i); + ul_win.raise_v_q(); + } + ul_win.receive_bsn(0); + ul_win.raise_v_q(); + ul_win.receive_bsn(1); + ul_win.raise_v_q(); + ul_win.update_rbb(win_rbb); + OSMO_ASSERT_STR_EQ(win_rbb, rbb); + OSMO_ASSERT(ul_win.ssn() == 2); } { -- To view, visit https://gerrit.osmocom.org/770 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ied0f1dd3037d8fac6a772f4e097defb72634f955 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 2 06:47:14 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 06:47:14 +0000 Subject: osmo-pcu[master]: Fix GPRS PUAN encoding: wrong BSN status In-Reply-To: References: Message-ID: Patch Set 3: Verified+1 -- To view, visit https://gerrit.osmocom.org/771 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I98e586aa5cb9200cf03e092556304211d4d459aa Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 06:47:18 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 06:47:18 +0000 Subject: [MERGED] osmo-pcu[master]: Fix GPRS PUAN encoding: wrong BSN status In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: Fix GPRS PUAN encoding: wrong BSN status ...................................................................... Fix GPRS PUAN encoding: wrong BSN status Earlier there was an incorrect encoding of BSN status in GPRS PUAN message. This was a bottle neck for GPRS performance testing for UL. Which has been fixed in this patch. Related: OS#1806 Change-Id: I98e586aa5cb9200cf03e092556304211d4d459aa --- M src/rlc.cpp M tests/types/TypesTest.cpp 2 files changed, 3 insertions(+), 4 deletions(-) Approvals: arvind.sirsikar: Verified Holger Freyther: Looks good to me, approved diff --git a/src/rlc.cpp b/src/rlc.cpp index e69d1fc..ee2635a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -227,7 +227,7 @@ { int i; for (i=0; i < ws(); i++) { - if (m_v_n.is_received(ssn()-1-i)) + if (m_v_n.is_received((ssn()-1-i) & mod_sns())) rbb[ws()-1-i] = 'R'; else rbb[ws()-1-i] = 'I'; diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp index c5654f6..8b3cfd1 100644 --- a/tests/types/TypesTest.cpp +++ b/tests/types/TypesTest.cpp @@ -325,10 +325,9 @@ /* * SSN wrap around case - * TODO: Should not expect any BSN as nacked. - * should be fixed in subsequent patch + * Should not expect any BSN as nacked. */ - rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR"; + rbb = "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"; for (int i = 0; i < 128; ++i) { ul_win.receive_bsn(i); ul_win.raise_v_q(); -- To view, visit https://gerrit.osmocom.org/771 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I98e586aa5cb9200cf03e092556304211d4d459aa Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 2 10:30:43 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 10:30:43 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: Verified+1 -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 10:30:54 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 10:30:54 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: Verified+1 -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:29:25 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Fri, 2 Sep 2016 11:29:25 +0000 Subject: osmo-pcu[master]: Update the function immediate assignment for EGPRS In-Reply-To: References: Message-ID: Patch Set 6: (1 comment) https://gerrit.osmocom.org/#/c/431/6/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 39: #include > why? Yes, its not necessary, will be removed and submitted -- To view, visit https://gerrit.osmocom.org/431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:34:25 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Fri, 2 Sep 2016 11:34:25 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 5: (6 comments) https://gerrit.osmocom.org/#/c/430/5/src/bts.cpp File src/bts.cpp: Line 520: /* class yet */ > /* multi okay, I will change and submit Line 576: if ((is_11bit == 0) && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { > is_11bit is boolean, right? It should be only 0 or 1? okay. I will be changed and submitted Line 584: "phase access,but we force two phase access\n"); > (space after comma) okay Line 588: } else if ((is_11bit == 1) && > if (is_11bit && ... I think else if is good enough, since only one condition will be true for one rach. Line 603: *priority = ((ra & 0x18) >> 3); > (unnecessary outer braces) okay Line 612: } else if ((is_11bit == 1) && > boolean okay -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:34:33 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 2 Sep 2016 11:34:33 +0000 Subject: osmo-pcu[master]: Fix DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 1: Hi Holger, Any conclusion on this patch? What i meant in my comment is there is an inconsistency in calculation of window size in below 2 cases 1) Re configuring 1 TS allocation to 4 TS allocation compared with 2) 4 TS allocation directly. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:36:56 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Fri, 2 Sep 2016 11:36:56 +0000 Subject: [PATCH] osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Hello Harald Welte, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/430 to look at the new patch set (#6). Handle EGPRS 11 bit RACH in osmo-pcu A function is_single_block is added to get request type of RACH. EGPRS 11 bit RACH is handled. Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 --- M src/bts.cpp M src/bts.h 2 files changed, 81 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/30/430/6 diff --git a/src/bts.cpp b/src/bts.cpp index e65d608..d16c84e 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -479,20 +479,16 @@ uint8_t usf = 7; uint8_t tsc; uint16_t ta; + uint16_t ms_class = 0; + uint16_t priority = 0; rach_frame(); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + if (qta < 0) qta = 0; if (qta > 252) @@ -515,8 +511,16 @@ } else { // Create new TBF #warning "Copy and paste with other routines.." - /* set class to 0, since we don't know the multislot class yet */ - tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + + if (is_11bit == 1) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0,as we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); /* FIXME: send reject */ @@ -564,6 +568,70 @@ return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (val == 0) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase access " + "but we force two phase access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access,but we force two phase access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index 801342d..ba6fc4d 100644 --- a/src/bts.h +++ b/src/bts.h @@ -290,6 +290,8 @@ int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst_type); -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:36:56 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Fri, 2 Sep 2016 11:36:56 +0000 Subject: [PATCH] osmo-pcu[master]: Update the function immediate assignment for EGPRS In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/431 to look at the new patch set (#7). Update the function immediate assignment for EGPRS Encode the EGPRS fields of immediate assignment message in uplink when EGPRS PACKET CHANNEL REQUEST (11 bit RACH) is received. The series of patches for 11 bit RACH are dependent on libosmocore and osmo-bts patches for 11 bit RACH. Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 --- M src/bts.cpp M src/encoding.cpp M src/encoding.h 3 files changed, 85 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/31/431/7 diff --git a/src/bts.cpp b/src/bts.cpp index d16c84e..b57f5da 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -555,7 +555,7 @@ plen = Encoding::write_immediate_assignment( tbf, immediate_assignment, 0, ra, Fn, ta, m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, - m_bts.alpha, m_bts.gamma, -1); + m_bts.alpha, m_bts.gamma, -1, burst_type, sb); if (plen >= 0) { pcu_l1if_tx_agch(immediate_assignment, plen); diff --git a/src/encoding.cpp b/src/encoding.cpp index 41e0d10..7d3fa14 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -147,11 +147,71 @@ gprs_rlcmac_ul_tbf *tbf, bitvec * dest, unsigned& wp, uint8_t usf, uint32_t fn, - uint8_t alpha, uint8_t gamma, int8_t ta_idx) + uint8_t alpha, uint8_t gamma, int8_t ta_idx, + enum ph_burst_type burst_type, uint16_t ra) { - LOGP(DRLCMACUL, LOGL_ERROR, - "EGPRS Packet Uplink Assignment is not yet implemented\n"); - return -EINVAL; + unsigned int ws_enc = 0; + uint8_t extended_ra = 0; + + extended_ra = (ra & 0x1F); + + bitvec_write_field(dest, wp, 1, 2); /* LH */ + bitvec_write_field(dest, wp, 0, 2); /* 0 EGPRS Uplink Assignment */ + bitvec_write_field(dest, wp, extended_ra, 5); /* Extended RA */ + bitvec_write_field(dest, wp, 0, 1); /* Access technology Request */ + + if (tbf == NULL) { + + bitvec_write_field(dest, wp, 0, 1); /* multiblock allocation */ + + if (alpha) { + bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + } else { + bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + } + + bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, wp, (fn / (26 * 51)) % 32, 5);/* T1' */ + bitvec_write_field(dest, wp, fn % 51, 6); /* T3 */ + bitvec_write_field(dest, wp, fn % 26, 5); /* T2 */ + bitvec_write_field(dest, wp, 0, 2); /* Radio block allocation */ + + bitvec_write_field(dest, wp, 0, 1); + + } else { + + ws_enc = (tbf->m_window.ws() - 64) / 32; + + bitvec_write_field(dest, wp, 1, 1); /* single block alloc */ + bitvec_write_field(dest, wp, tbf->tfi(), 5);/* TFI assignment */ + bitvec_write_field(dest, wp, 0, 1); /* polling bit */ + bitvec_write_field(dest, wp, 0, 1); /* constant */ + bitvec_write_field(dest, wp, usf, 3); /* USF bit */ + bitvec_write_field(dest, wp, 0, 1); /* USF granularity */ + bitvec_write_field(dest, wp, 0, 1); /* P0 */ + /* MCS */ + bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 4); + /* tlli channel block */ + bitvec_write_field(dest, wp, tbf->tlli(), 1); + bitvec_write_field(dest, wp, 0, 1); /* BEP period present */ + bitvec_write_field(dest, wp, 0, 1); /* resegmentation */ + bitvec_write_field(dest, wp, ws_enc, 5);/* egprs window_size */ + + if (alpha) { + bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + } else { + bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + } + + bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, wp, 0, 1); /* TIMING_ADVANCE_INDEX */ + bitvec_write_field(dest, wp, 0, 1); /* TBF_STARTING_TIME_FLAG */ + bitvec_write_field(dest, wp, 0, 1); /* NULL */ + } + + return 0; } /* @@ -160,10 +220,10 @@ */ int Encoding::write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t usf, uint8_t polling, uint32_t fn, uint8_t alpha, - uint8_t gamma, int8_t ta_idx) + uint8_t gamma, int8_t ta_idx, enum ph_burst_type burst_type, uint8_t sb) { unsigned wp = 0; int plen; @@ -189,7 +249,13 @@ bitvec_write_field(dest, wp,arfcn,10); // ARFCN //10.5.2.30 Request Reference - bitvec_write_field(dest, wp,ra,8); // RA + if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + bitvec_write_field(dest, wp, 0x7f, 8); /* RACH value */ + } else { + bitvec_write_field(dest, wp, ra, 8); /* RACH value */ + } + bitvec_write_field(dest, wp,(ref_fn / (26 * 51)) % 32,5); // T1' bitvec_write_field(dest, wp,ref_fn % 51,6); // T3 bitvec_write_field(dest, wp,ref_fn % 26,5); // T2 @@ -213,10 +279,11 @@ rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp, polling, gsm48_ta_is_valid(ta), fn, alpha, gamma, ta_idx); - else if (as_ul_tbf(tbf) && as_ul_tbf(tbf)->is_egprs_enabled()) + else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) rc = write_ia_rest_egprs_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, - alpha, gamma, ta_idx); + alpha, gamma, ta_idx, burst_type, ra); else rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, diff --git a/src/encoding.h b/src/encoding.h index 710de78..69f8cdc 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -23,6 +23,9 @@ #include #include #include +extern "C" { +#include +} struct gprs_rlcmac_bts; struct gprs_rlcmac_tbf; @@ -40,11 +43,14 @@ public: static int write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t usf, uint8_t polling, uint32_t fn, uint8_t alpha, uint8_t gamma, - int8_t ta_idx); + int8_t ta_idx, + enum ph_burst_type burst_type = + GSM_L1_BURST_TYPE_ACCESS_0, + uint8_t sb = 1); static void write_packet_uplink_assignment( struct gprs_rlcmac_bts *bts, -- To view, visit https://gerrit.osmocom.org/431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add SNDCP-XID encoder/decoder and unit test In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/641 to look at the new patch set (#15). SNDCP: add SNDCP-XID encoder/decoder and unit test The SNDCP-XID (or layer-3 xid) is used to exchange layer-3 parameters such as compression. The encoder encodes a bytestream that is then sent as regular XID field from LLC. We will need the SNDCP-XID to negotiate the parameters for our upcomming GPRS data and header compression features Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_xid.h M openbsc/src/gprs/Makefile.am A openbsc/src/gprs/gprs_sndcp_xid.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/sndcp_xid/Makefile.am A openbsc/tests/sndcp_xid/sndcp_xid_test.c A openbsc/tests/sndcp_xid/sndcp_xid_test.ok M openbsc/tests/testsuite.at 12 files changed, 2,347 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/41/641/15 diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 518a960..8ce3b70 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -82,6 +82,7 @@ tests/gtphub/gtphub_test tests/mm_auth/mm_auth_test tests/xid/xid_test +tests/sndcp_xid/sndcp_xid_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index f63d61f..9dc2f8d 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -231,6 +231,7 @@ tests/gtphub/Makefile tests/mm_auth/Makefile tests/xid/Makefile + tests/sndcp_xid/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..a5ba3ef 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -18,7 +18,7 @@ gprs_gb_parse.h smpp.h meas_feed.h \ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ + gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ iu.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h diff --git a/openbsc/include/openbsc/gprs_sndcp_xid.h b/openbsc/include/openbsc/gprs_sndcp_xid.h new file mode 100644 index 0000000..02904a7 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_xid.h @@ -0,0 +1,216 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include + +#define CURRENT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ +#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit + * for compression enitity number */ + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ +#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ + +/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control + * information compression field (Figure 7) and 3GPP TS 44.065, + * 6.6.1.1 Format of the data compression field (Figure 9) */ +struct gprs_sndcp_comp_field { + struct llist_head list; + + /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ + unsigned int p; + + /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int entity; + + /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ + int algo; + + /* Number of contained PCOMP / DCOMP values */ + uint8_t comp_len; + + /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ + uint8_t comp[MAX_COMP]; + + /* Note: Only one of the following struct pointers may, + be used. Unused pointers must be set to NULL! */ + struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; + struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; + struct gprs_sndcp_pcomp_rohc_params *rohc_params; + struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; + struct gprs_sndcp_dcomp_v44_params *v44_params; +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_hdr_comp_algo { + RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ + RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ + ROHC /* Robust Header Compression, see also 6.5.4 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_data_comp_algo { + V42BIS, /* V.42bis data compression, see also 6.6.2 */ + V44 /* V44 data compression, see also: 6.6.3 */ +}; + +/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ +enum gprs_sndcp_xid_param_types { + SNDCP_XID_VERSION_NUMBER, + SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ + SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ +struct gprs_sndcp_pcomp_rfc1144_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int s01; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ +enum gprs_sndcp_pcomp_rfc1144_pcomp { + RFC1144_PCOMP1, /* Uncompressed TCP */ + RFC1144_PCOMP2, /* Compressed TCP */ + RFC1144_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ +struct gprs_sndcp_pcomp_rfc2507_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int f_max_period; /* (default 256) */ + int f_max_time; /* (default 5) */ + int max_header; /* (default 168) */ + int tcp_space; /* (default 15) */ + int non_tcp_space; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ +enum gprs_sndcp_pcomp_rfc2507_pcomp { + RFC2507_PCOMP1, /* Full Header */ + RFC2507_PCOMP2, /* Compressed TCP */ + RFC2507_PCOMP3, /* Compressed TCP non delta */ + RFC2507_PCOMP4, /* Compressed non TCP */ + RFC2507_PCOMP5, /* Context state */ + RFC2507_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ +struct gprs_sndcp_pcomp_rohc_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int max_cid; /* (default 15) */ + int max_header; /* (default 168) */ + uint8_t profile_len; /* (default 1) */ + uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ +enum gprs_sndcp_pcomp_rohc_pcomp { + ROHC_PCOMP1, /* ROHC small CIDs */ + ROHC_PCOMP2, /* ROHC large CIDs */ + ROHC_PCOMP_NUM /* Number of pcomp values */ +}; + +/* ROHC compression profiles, see also: + http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ +enum gprs_sndcp_xid_rohc_profiles { + ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ + ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ + ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ + ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ + ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ + ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ + ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ + ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ + ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ + ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ + ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ + ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ + ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ + ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ + ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ + ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ +}; + +/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ +struct gprs_sndcp_dcomp_v42bis_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int p0; /* (default 3) */ + int p1; /* (default 2048) */ + int p2; /* (default 20) */ + +}; + +/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v42bis_dcomp { + V42BIS_DCOMP1, /* V.42bis enabled */ + V42BIS_DCOMP_NUM /* Number of dcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ +struct gprs_sndcp_dcomp_v44_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int c0; /* (default 10000000) */ + int p0; /* (default 3) */ + int p1t; /* Refer to subclause 6.6.3.1.4 */ + int p1r; /* Refer to subclause 6.6.3.1.5 */ + int p3t; /* (default 3 x p1t) */ + int p3r; /* (default 3 x p1r) */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v44_dcomp { + V44_DCOMP1, /* Packet method compressed */ + V44_DCOMP2, /* Multi packet method compressed */ + V44_DCOMP_NUM /* Number of dcomp values */ +}; + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields); + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t * src, + unsigned int src_len, + const struct llist_head *comp_fields_req); + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class( + const struct gprs_sndcp_comp_field *comp_field); + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl); + diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 1b6de46..fa4a3dd 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -26,11 +26,11 @@ sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c + oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt + $(LIBCRYPTO_LIBS) -lrt -lm osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \ gtphub_vty.c sgsn_ares.c gprs_utils.c diff --git a/openbsc/src/gprs/gprs_sndcp_xid.c b/openbsc/src/gprs/gprs_sndcp_xid.c new file mode 100644 index 0000000..270bdee --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_xid.c @@ -0,0 +1,1803 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* When the propose bit in an SNDCP-XID compression field is set to zero, + * the algorithm identifier is stripped. The algoritm parameters are specific + * for each algorithms. The following struct is used to pass the information + * about the referenced algorithm to the parser. */ +struct entity_algo_table { + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */ + unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or + SNDCP_XID_PROTOCOL_COMPRESSION */ +}; + +/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */ + +/* Encode applicable sapis (works the same in all three compression schemes) */ +static int encode_pcomp_applicable_sapis(uint8_t *dst, + const uint8_t *nsapis, + uint8_t nsapis_len) +{ + /* NOTE: Buffer *dst needs offer at 2 bytes + * of space to store the generation results */ + + uint16_t blob; + uint8_t nsapi; + int i; + + /* Bail if number of possible nsapis exceeds valid range + * (Only 11 nsapis possible for PDP-Contexts) */ + OSMO_ASSERT(nsapis_len <= 11); + + /* Encode applicable SAPIs */ + blob = 0; + for (i = 0; i < nsapis_len; i++) { + nsapi = nsapis[i]; + /* Only NSAPI 5 to 15 are applicable for user traffic (PDP- + * contexts). Only for these NSAPIs SNDCP-XID parameters + * can apply. See also 3GPP TS 44.065, 5.1 Service primitives */ + OSMO_ASSERT(nsapi >= 5 && nsapi <= 15); + blob |= (1 << nsapi); + } + + /* Store result */ + *dst = (blob >> 8) & 0xFF; + dst++; + *dst = blob & 0xFF; + + return 2; +} + +/* Encode rfc1144 parameter field + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int encode_pcomp_rfc1144_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc1144_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 3); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode s01 (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + OSMO_ASSERT(params->s01 >= 0); + OSMO_ASSERT(params->s01 <= 255); + *dst = params->s01; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* + * Encode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) + */ +static int encode_pcomp_rfc2507_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc2507_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 9); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_period >= 1); + OSMO_ASSERT(params->f_max_period <= 65535); + *dst = (params->f_max_period >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->f_max_period) & 0xFF; + dst++; + dst_counter++; + + /* Encode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_time >= 1); + OSMO_ASSERT(params->f_max_time <= 255); + *dst = params->f_max_time; + dst++; + dst_counter++; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = params->max_header; + dst++; + dst_counter++; + + /* Encode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->tcp_space >= 3); + OSMO_ASSERT(params->tcp_space <= 255); + *dst = params->tcp_space; + dst++; + dst_counter++; + + /* Encode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->non_tcp_space >= 3); + OSMO_ASSERT(params->non_tcp_space <= 65535); + *dst = (params->non_tcp_space >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->non_tcp_space) & 0xFF; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode ROHC parameter field + * (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int encode_pcomp_rohc_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_pcomp_rohc_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 36 + * (2 * 16 Profiles + 2 * 3 Parameter) bytes + * of memory space to store generation results */ + + int i; + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 38); + + /* Bail if number of ROHC profiles exceeds limit + * (ROHC supports only a maximum of 16 different profiles) */ + OSMO_ASSERT(params->profile_len >= 0); + OSMO_ASSERT(params->profile_len <= 16); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_cid >= 0); + OSMO_ASSERT(params->max_cid <= 16383); + *dst = (params->max_cid >> 8) & 0xFF; + dst++; + *dst = params->max_cid & 0xFF; + dst++; + dst_counter += 2; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = (params->max_header >> 8) & 0xFF; + dst++; + *dst = params->max_header & 0xFF; + dst++; + dst_counter += 2; + + /* Encode ROHC Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < params->profile_len; i++) { + *dst = (params->profile[i] >> 8) & 0xFF; + dst++; + *dst = params->profile[i] & 0xFF; + dst++; + dst_counter += 2; + } + + /* Return generated length */ + return dst_counter; +} + +/* Encode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int encode_dcomp_v42bis_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_dcomp_v42bis_params *params) +{ + /* NOTE: Buffer *dst should offer at least 6 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 6); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p1 >= 512); + OSMO_ASSERT(params->p1 <= 65535); + *dst = (params->p1 >> 8) & 0xFF; + dst++; + *dst = params->p1 & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p2 >= 6); + OSMO_ASSERT(params->p2 <= 250); + *dst = params->p2; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode V44 parameter field + * (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int encode_dcomp_v44_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_dcomp_v44_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 12 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 12); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->c0 == 0x80 || params->c0 == 0xC0); + *dst = params->c0 & 0xC0; + dst++; + dst_counter++; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1t >= 256); + OSMO_ASSERT(params->p1t <= 65535); + *dst = (params->p1t >> 8) & 0xFF; + dst++; + *dst = params->p1t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1r >= 256); + OSMO_ASSERT(params->p1r <= 65535); + *dst = (params->p1r >> 8) & 0xFF; + dst++; + *dst = params->p1r & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3t >= 0); + OSMO_ASSERT(params->p3t <= 65535); + OSMO_ASSERT(params->p3t >= 2 * params->p1t); + *dst = (params->p3t >> 8) & 0xFF; + dst++; + *dst = params->p3t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3r >= 0); + OSMO_ASSERT(params->p3r <= 65535); + OSMO_ASSERT(params->p3r >= 2 * params->p1r); + *dst = (params->p3r >> 8) & 0xFF; + dst++; + *dst = params->p3r & 0xFF; + dst++; + dst_counter += 2; + + /* Return generated length */ + return dst_counter; +} + +/* Encode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_comp_field *comp_field) +{ + int dst_counter = 0; + int len; + int expected_length; + int i; + + uint8_t payload_bytes[256]; + int payload_bytes_len = -1; + + /* If possible, try do encode payload bytes first */ + if (comp_field->rfc1144_params) { + payload_bytes_len = + encode_pcomp_rfc1144_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc1144_params); + } else if (comp_field->rfc2507_params) { + payload_bytes_len = + encode_pcomp_rfc2507_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc2507_params); + } else if (comp_field->rohc_params) { + payload_bytes_len = + encode_pcomp_rohc_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rohc_params); + } else if (comp_field->v42bis_params) { + payload_bytes_len = + encode_dcomp_v42bis_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v42bis_params); + } else if (comp_field->v44_params) { + payload_bytes_len = + encode_dcomp_v44_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v44_params); + } else + OSMO_ASSERT(false); + + /* Bail immediately if payload byte generation failed */ + OSMO_ASSERT(payload_bytes_len >= 0); + + /* Bail if comp_len is out of bounds */ + OSMO_ASSERT(comp_field->comp_len <= sizeof(comp_field->comp)); + + /* Calculate length field of the data block */ + if (comp_field->p) { + len = + payload_bytes_len + + ceil((double)(comp_field->comp_len) / 2.0); + expected_length = len + 3; + } else { + len = payload_bytes_len; + expected_length = len + 2; + } + + /* Bail immediately if no sufficient memory space is supplied */ + OSMO_ASSERT(dst_maxlen >= expected_length); + + /* Check if the entity number is within bounds */ + OSMO_ASSERT(comp_field->entity <= 0x1f); + + /* Check if the algorithm number is within bounds */ + OSMO_ASSERT(comp_field->algo >= 0 || comp_field->algo <= 0x1f); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode Propose bit */ + if (comp_field->p) + *dst |= (1 << 7); + + /* Encode entity number */ + *dst |= comp_field->entity & 0x1F; + dst++; + dst_counter++; + + /* Encode algorithm number */ + if (comp_field->p) { + *dst |= comp_field->algo & 0x1F; + dst++; + dst_counter++; + } + + /* Encode length field */ + *dst |= len & 0xFF; + dst++; + dst_counter++; + + /* Encode PCOMP/DCOMP values */ + if (comp_field->p) { + for (i = 0; i < comp_field->comp_len; i++) { + /* Check if submitted PCOMP/DCOMP + values are within bounds */ + if ((comp_field->comp[i] < 0) + || (comp_field->comp[i] > 0x0F)) + return -EINVAL; + + if (i & 1) { + *dst |= comp_field->comp[i] & 0x0F; + dst++; + dst_counter++; + } else + *dst |= (comp_field->comp[i] << 4) & 0xF0; + } + + if (i & 1) { + dst++; + dst_counter++; + } + } + + /* Append payload bytes */ + memcpy(dst, payload_bytes, payload_bytes_len); + dst_counter += payload_bytes_len; + + /* Return generated length */ + return dst_counter; +} + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field + *comp_field) +{ + OSMO_ASSERT(comp_field); + + if (comp_field->rfc1144_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rfc2507_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rohc_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->v42bis_params) + return SNDCP_XID_DATA_COMPRESSION; + else if (comp_field->v44_params) + return SNDCP_XID_DATA_COMPRESSION; + else + return -EINVAL; +} + +/* Convert all compression fields to bytstreams */ +static int gprs_sndcp_pack_fields(const struct llist_head *comp_fields, + uint8_t *dst, + unsigned int dst_maxlen, int class) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int rc; + + llist_for_each_entry_reverse(comp_field, comp_fields, list) { + if (class == gprs_sndcp_get_compression_class(comp_field)) { + rc = encode_comp_field(dst + byte_counter, + dst_maxlen - byte_counter, + comp_field); + + /* When input data is correct, there is + * no reason for the encoder to fail! */ + OSMO_ASSERT(rc >= 0); + + byte_counter += rc; + } + } + + /* Return generated length */ + return byte_counter; +} + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields) +{ + int rc; + int byte_counter = 0; + uint8_t comp_bytes[512]; + uint8_t xid_version_number[1] = { CURRENT_SNDCP_VERSION }; + + OSMO_ASSERT(comp_fields); + OSMO_ASSERT(dst); + OSMO_ASSERT(dst_maxlen >= 2 + sizeof(xid_version_number)); + + /* Bail if there is no input */ + if (llist_empty(comp_fields)) + return -EINVAL; + + /* Prepend header */ + dst = + tlv_put(dst, SNDCP_XID_VERSION_NUMBER, + sizeof(xid_version_number), xid_version_number); + byte_counter += (sizeof(xid_version_number) + 2); + + /* Add data compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_DATA_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_DATA_COMPRESSION, rc, comp_bytes); + byte_counter += rc + 2; + } + + /* Add header compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_PROTOCOL_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_PROTOCOL_COMPRESSION, rc, + comp_bytes); + byte_counter += rc + 2; + } + + /* Return generated length */ + return byte_counter; +} + +/* FUNCTIONS RELATED TO SNDCP-XID DECODING */ + +/* Decode applicable sapis (works the same in all three compression schemes) */ +static int decode_pcomp_applicable_sapis(uint8_t *nsapis, + uint8_t *nsapis_len, + const uint8_t *src, + unsigned int src_len) +{ + uint16_t blob; + int i; + int nsapi_len = 0; + + /* Exit immediately if no result can be stored */ + if (!nsapis) + return -EINVAL; + + /* Exit immediately if not enough input data is available */ + if (src_len < 2) + return -EINVAL; + + /* Read bitmask */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= (*src) & 0xFF; + blob = (blob >> 5); + + /* Decode applicable SAPIs */ + for (i = 0; i < 15; i++) { + if ((blob >> i) & 1) { + nsapis[nsapi_len] = i + 5; + nsapi_len++; + } + } + + /* Return consumed length */ + *nsapis_len = nsapi_len; + return 2; +} + +/* Decode 16 bit field */ +static int decode_pcomp_16_bit_field(int *value_int, uint16_t * value_uint16, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint16_t blob; + + /* Reset values to zero (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint16) + *value_uint16 = 0; + + /* Exit if not enough src are available */ + if (src_len < 2) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint16) + *value_uint16 = blob; + + /* Return consumed length */ + return 2; +} + +/* Decode 8 bit field */ +static int decode_pcomp_8_bit_field(int *value_int, uint8_t *value_uint8, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint8_t blob; + + /* Reset values to invalid (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint8) + *value_uint8 = 0; + + /* Exit if not enough src are available */ + if (src_len < 1) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint8) + *value_uint8 = blob; + + /* Return consumed length */ + return 1; +} + +/* Decode rfc1144 parameter field see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int decode_pcomp_rfc1144_params(struct gprs_sndcp_pcomp_rfc1144_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->s01 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode parameter S0 -1 + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + rc = decode_pcomp_8_bit_field(¶ms->s01, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ +static int decode_pcomp_rfc2507_params(struct gprs_sndcp_pcomp_rfc2507_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->f_max_period = -1; + params->f_max_time = -1; + params->max_header = -1; + params->tcp_space = -1; + params->non_tcp_space = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->f_max_period, NULL, src, + src_len - byte_counter, 1, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->f_max_time, NULL, src, + src_len - byte_counter, 1, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->tcp_space, NULL, src, + src_len - byte_counter, 3, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->non_tcp_space, NULL, src, + src_len - byte_counter, 3, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode ROHC parameter field (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int decode_pcomp_rohc_params(struct gprs_sndcp_pcomp_rohc_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + int i; + + /* Mark all optional parameters invalid by default */ + params->max_cid = -1; + params->max_header = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_cid, NULL, src, + src_len - byte_counter, 0, 16383); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < 16; i++) { + params->profile_len = 0; + rc = decode_pcomp_16_bit_field(NULL, ¶ms->profile[i], src, + src_len - byte_counter, 0, + 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + params->profile_len = i + 1; + } + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int decode_dcomp_v42bis_params(struct gprs_sndcp_dcomp_v42bis_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->p0 = -1; + params->p1 = -1; + params->p2 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_16_bit_field(¶ms->p1, NULL, src, + src_len - byte_counter, 512, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p2, NULL, src, + src_len - byte_counter, 6, 250); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V44 parameter field (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->c0 = -1; + params->p0 = -1; + params->p1t = -1; + params->p1r = -1; + params->p3t = -1; + params->p3r = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->c0, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + if ((params->c0 != 0x80) && (params->c0 != 0xC0)) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3t < 2 * params->p1t) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3r < 2 * params->p1r) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Lookup algorithm identfier by entity ID */ +static int lookup_algorithm_identifier(int entity, const struct + entity_algo_table + *lt, unsigned int lt_len, int compclass) +{ + int i; + + if (!lt) + return -1; + + for (i = 0; i < lt_len; i++) { + if ((lt[i].entity == entity) + && (lt[i].compclass == compclass)) + return lt[i].algo; + } + + return -1; +} + +/* Helper function for decode_comp_field(), decodes + * numeric pcomp/dcomp values */ +static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int compclass) +{ + int src_counter = 0; + int i; + + if (comp_field->p) { + /* Determine the number of expected PCOMP/DCOMP values */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + /* For protocol compression */ + switch (comp_field->algo) { + case RFC_1144: + comp_field->comp_len = RFC1144_PCOMP_NUM; + break; + case RFC_2507: + comp_field->comp_len = RFC2507_PCOMP_NUM; + break; + case ROHC: + comp_field->comp_len = ROHC_PCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } else { + /* For data compression */ + switch (comp_field->algo) { + case V42BIS: + comp_field->comp_len = V42BIS_DCOMP_NUM; + break; + case V44: + comp_field->comp_len = V44_DCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } + + for (i = 0; i < comp_field->comp_len; i++) { + if (i & 1) { + comp_field->comp[i] = (*src) & 0x0F; + src++; + src_counter++; + } else + comp_field->comp[i] = ((*src) >> 4) & 0x0F; + } + + if (i & 1) { + src++; + src_counter++; + } + } + + return src_counter; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are protocol compression specific */ +static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case RFC_1144: + comp_field->rfc1144_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc1144_params); + rc = decode_pcomp_rfc1144_params(comp_field->rfc1144_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case RFC_2507: + comp_field->rfc2507_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc2507_params); + rc = decode_pcomp_rfc2507_params(comp_field->rfc2507_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case ROHC: + comp_field->rohc_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rohc_params); + rc = decode_pcomp_rohc_params(comp_field->rohc_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->rohc_params); + break; + + /* If no suitable decoder is detected, + leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->rfc1144_params = NULL; + comp_field->rfc2507_params = NULL; + comp_field->rohc_params = NULL; + } + + return rc; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are data compression specific */ +static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case V42BIS: + comp_field->v42bis_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v42bis_params); + rc = decode_dcomp_v42bis_params(comp_field->v42bis_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v42bis_params); + break; + case V44: + comp_field->v44_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v44_params); + rc = decode_dcomp_v44_params(comp_field->v44_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v44_params); + break; + + /* If no suitable decoder is detected, + * leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->v42bis_params = NULL; + comp_field->v44_params = NULL; + } + + return rc; +} + +/* Decode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, unsigned int src_len, + const struct entity_algo_table *lt, + unsigned int lt_len, int compclass) +{ + int src_counter = 0; + unsigned int len; + int rc; + + OSMO_ASSERT(comp_field); + + /* Exit immediately if it is clear that no + parseable data is present */ + if (src_len < 1 || !src) + return -EINVAL; + + /* Zero out target struct */ + memset(comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Decode Propose bit and Entity number */ + if ((*src) & 0x80) + comp_field->p = 1; + comp_field->entity = (*src) & 0x1F; + src_counter++; + src++; + + /* Decode algorithm number (if present) */ + if (comp_field->p) { + comp_field->algo = (*src) & 0x1F; + src_counter++; + src++; + } + /* Alternatively take the information from the lookup table */ + else + comp_field->algo = + lookup_algorithm_identifier(comp_field->entity, lt, + lt_len, compclass); + + /* Decode length field */ + len = *src; + src_counter++; + src++; + + /* Decode PCOMP/DCOMP values */ + rc = decode_comp_values(comp_field, src, compclass); + if (rc < 0) + return -EINVAL; + src_counter += rc; + src += rc; + len -= rc; + + /* Decode algorithm specific payload data */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = decode_pcomp_params(comp_field, src, len); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = decode_dcomp_params(comp_field, src, len); + else + return -EINVAL; + + if (rc >= 0) + src_counter += rc; + else + return -EINVAL; + + /* Return consumed length */ + return src_counter; +} + +/* Helper function for gprs_sndcp_decode_xid() to decode XID blocks */ +static int decode_xid_block(struct llist_head *comp_fields, uint8_t tag, + uint16_t tag_len, const uint8_t *val, + const struct entity_algo_table *lt, + unsigned int lt_len) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int comp_field_count = 0; + int rc; + + byte_counter = 0; + do { + /* Bail if more than the maximum number of + comp_fields is generated */ + if (comp_field_count > MAX_ENTITIES * 2) { + return -EINVAL; + } + + /* Parse and add comp_field */ + comp_field = + talloc_zero(comp_fields, struct gprs_sndcp_comp_field); + + rc = decode_comp_field(comp_field, val + byte_counter, + tag_len - byte_counter, lt, lt_len, tag); + + if (rc < 0) { + talloc_free(comp_field); + return -EINVAL; + } + + byte_counter += rc; + llist_add(&comp_field->list, comp_fields); + comp_field_count++; + } + while (tag_len - byte_counter > 0); + + return byte_counter; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +static int gprs_sndcp_decode_xid(struct llist_head *comp_fields, + const uint8_t *src, unsigned int src_len, + const struct + entity_algo_table + *lt, unsigned int lt_len) +{ + int src_pos = 0; + uint8_t tag; + uint16_t tag_len; + const uint8_t *val; + int byte_counter = 0; + int rc; + int tlv_count = 0; + + /* Valid TLV-Tag and types */ + static const struct tlv_definition sndcp_xid_def = { + .def = { + [SNDCP_XID_VERSION_NUMBER] = {TLV_TYPE_TLV,}, + [SNDCP_XID_DATA_COMPRESSION] = {TLV_TYPE_TLV,}, + [SNDCP_XID_PROTOCOL_COMPRESSION] = {TLV_TYPE_TLV,}, + }, + }; + + /* Parse TLV-Encoded SNDCP-XID message and defer payload + to the apporpiate sub-parser functions */ + while (1) { + + /* Bail if an the maximum number of TLV fields + * have been parsed */ + if (tlv_count >= 3) { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Parse TLV field */ + rc = tlv_parse_one(&tag, &tag_len, &val, &sndcp_xid_def, + src + src_pos, src_len - src_pos); + if (rc > 0) + src_pos += rc; + else { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Decode compression parameters */ + if ((tag == SNDCP_XID_PROTOCOL_COMPRESSION) + || (tag == SNDCP_XID_DATA_COMPRESSION)) { + rc = decode_xid_block(comp_fields, tag, tag_len, val, + lt, lt_len); + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } else + byte_counter += rc; + } + + /* Stop when no further TLV elements can be expected */ + if (src_len - src_pos <= 2) + break; + + tlv_count++; + } + + return 0; +} + +/* Fill up lookutable from a list with comression entitiy fields */ +static int gprs_sndcp_fill_table(struct + entity_algo_table *lt, + unsigned int lt_len, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field; + int i = 0; + + if (!comp_fields) + return -EINVAL; + if (!lt) + return -EINVAL; + + memset(lt, 0, lt_len * sizeof(lt)); + + llist_for_each_entry(comp_field, comp_fields, list) { + + lt[i].entity = comp_field->entity; + lt[i].algo = comp_field->algo; + lt[i].compclass = gprs_sndcp_get_compression_class(comp_field); + + if (lt[i].compclass < 0) { + memset(lt, 0, lt_len * sizeof(lt)); + return -EINVAL; + } + + i++; + } + + return i; +} + +/* Complete comp field params + * (if a param (dst) is not valid, it will be copied from source (src) */ +static int complete_comp_field_params(struct gprs_sndcp_comp_field + *comp_field_dst, const struct + gprs_sndcp_comp_field *comp_field_src) +{ + if (comp_field_dst->algo < 0) + return -EINVAL; + + if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) { + if (comp_field_dst->rfc1144_params->s01 < 0) { + comp_field_dst->rfc1144_params->s01 = + comp_field_src->rfc1144_params->s01; + } + return 0; + } + + if (comp_field_dst->rfc2507_params && comp_field_src->rfc2507_params) { + + if (comp_field_dst->rfc2507_params->f_max_period < 0) { + comp_field_dst->rfc2507_params->f_max_period = + comp_field_src->rfc2507_params->f_max_period; + } + if (comp_field_dst->rfc2507_params->f_max_time < 0) { + comp_field_dst->rfc2507_params->f_max_time = + comp_field_src->rfc2507_params->f_max_time; + } + if (comp_field_dst->rfc2507_params->max_header < 0) { + comp_field_dst->rfc2507_params->max_header = + comp_field_src->rfc2507_params->max_header; + } + if (comp_field_dst->rfc2507_params->tcp_space < 0) { + comp_field_dst->rfc2507_params->tcp_space = + comp_field_src->rfc2507_params->tcp_space; + } + if (comp_field_dst->rfc2507_params->non_tcp_space < 0) { + comp_field_dst->rfc2507_params->non_tcp_space = + comp_field_src->rfc2507_params->non_tcp_space; + } + return 0; + } + + if (comp_field_dst->rohc_params && comp_field_src->rohc_params) { + if (comp_field_dst->rohc_params->max_cid < 0) { + comp_field_dst->rohc_params->max_cid = + comp_field_src->rohc_params->max_cid; + } + if (comp_field_dst->rohc_params->max_header < 0) { + comp_field_dst->rohc_params->max_header = + comp_field_src->rohc_params->max_header; + } + if (comp_field_dst->rohc_params->profile_len > 0) { + memcpy(comp_field_dst->rohc_params->profile, + comp_field_src->rohc_params->profile, + sizeof(comp_field_dst->rohc_params->profile)); + comp_field_dst->rohc_params->profile_len = + comp_field_src->rohc_params->profile_len; + } + + return 0; + } + + if (comp_field_dst->v42bis_params && comp_field_src->v42bis_params) { + if (comp_field_dst->v42bis_params->p0 < 0) { + comp_field_dst->v42bis_params->p0 = + comp_field_src->v42bis_params->p0; + } + if (comp_field_dst->v42bis_params->p1 < 0) { + comp_field_dst->v42bis_params->p1 = + comp_field_src->v42bis_params->p1; + } + if (comp_field_dst->v42bis_params->p2 < 0) { + comp_field_dst->v42bis_params->p2 = + comp_field_src->v42bis_params->p2; + } + return 0; + } + + if (comp_field_dst->v44_params && comp_field_src->v44_params) { + if (comp_field_dst->v44_params->c0 < 0) { + comp_field_dst->v44_params->c0 = + comp_field_src->v44_params->c0; + } + if (comp_field_dst->v44_params->p0 < 0) { + comp_field_dst->v44_params->p0 = + comp_field_src->v44_params->p0; + } + if (comp_field_dst->v44_params->p1t < 0) { + comp_field_dst->v44_params->p1t = + comp_field_src->v44_params->p1t; + } + if (comp_field_dst->v44_params->p1r < 0) { + comp_field_dst->v44_params->p1r = + comp_field_src->v44_params->p1r; + } + if (comp_field_dst->v44_params->p3t < 0) { + comp_field_dst->v44_params->p3t = + comp_field_src->v44_params->p3t; + } + if (comp_field_dst->v44_params->p3r < 0) { + comp_field_dst->v44_params->p3r = + comp_field_src->v44_params->p3r; + } + return 0; + } + + /* There should be at least exist one param set + * in the destination struct, otherwise something + * must be wrong! */ + return -EINVAL; +} + +/* Complete missing parameters in a comp_field */ +static int gprs_sndcp_complete_comp_field(struct gprs_sndcp_comp_field + *comp_field, const struct llist_head + *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_src; + int rc = 0; + + llist_for_each_entry(comp_field_src, comp_fields, list) { + if (comp_field_src->entity == comp_field->entity) { + + /* Complete header fields */ + if (comp_field_src->comp_len > 0) { + memcpy(comp_field->comp, + comp_field_src->comp, + sizeof(comp_field_src->comp)); + comp_field->comp_len = comp_field_src->comp_len; + } + + /* Complete parameter fields */ + rc = complete_comp_field_params(comp_field, + comp_field_src); + } + } + + return rc; +} + +/* Complete missing parameters of all comp_field in a list */ +static int gprs_sndcp_complete_comp_fields(struct llist_head + *comp_fields_incomplete, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_incomplete; + int rc; + + llist_for_each_entry(comp_field_incomplete, comp_fields_incomplete, + list) { + + rc = gprs_sndcp_complete_comp_field(comp_field_incomplete, + comp_fields); + if (rc < 0) + return -EINVAL; + + } + + return 0; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t *src, + unsigned int src_len, + const struct llist_head + *comp_fields_req) +{ + int rc; + int lt_len; + struct llist_head *comp_fields; + struct entity_algo_table lt[MAX_ENTITIES * 2]; + + OSMO_ASSERT(src); + + comp_fields = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(comp_fields); + + if (comp_fields_req) { + /* Generate lookup table */ + lt_len = + gprs_sndcp_fill_table(lt, MAX_ENTITIES * 2, + comp_fields_req); + if (lt_len < 0) { + talloc_free(comp_fields); + return NULL; + } + + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, lt, + lt_len); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + rc = gprs_sndcp_complete_comp_fields(comp_fields, + comp_fields_req); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + } else { + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, NULL, 0); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + } + + return comp_fields; +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * dumps protocol compression parameters */ +static void dump_pcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case RFC_1144: + if (comp_field->rfc1144_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc1144_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc1144_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc1144_params->nsapi_len); + if (comp_field->rfc1144_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc1144_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc1144_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " s01=%d;\n", + comp_field->rfc1144_params->s01); + LOGP(DSNDCP, logl, " }\n"); + break; + case RFC_2507: + if (comp_field->rfc2507_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc2507_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc2507_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc2507_params->nsapi_len); + if (comp_field->rfc2507_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc2507_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc2507_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " f_max_period=%d;\n", + comp_field->rfc2507_params->f_max_period); + LOGP(DSNDCP, logl, + " f_max_time=%d;\n", + comp_field->rfc2507_params->f_max_time); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rfc2507_params->max_header); + LOGP(DSNDCP, logl, + " tcp_space=%d;\n", + comp_field->rfc2507_params->tcp_space); + LOGP(DSNDCP, logl, + " non_tcp_space=%d;\n", + comp_field->rfc2507_params->non_tcp_space); + LOGP(DSNDCP, logl, " }\n"); + break; + case ROHC: + if (comp_field->rohc_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rohc_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rohc_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rohc_params->nsapi_len); + if (comp_field->rohc_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rohc_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " max_cid=%d;\n", comp_field->rohc_params->max_cid); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rohc_params->max_header); + LOGP(DSNDCP, logl, + " profile_len=%d;\n", + comp_field->rohc_params->profile_len); + if (comp_field->rohc_params->profile_len == 0) + LOGP(DSNDCP, logl, " profile[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->profile_len; i++) + LOGP(DSNDCP, logl, + " profile[%d]=%04x;\n", + i, comp_field->rohc_params->profile[i]); + LOGP(DSNDCP, logl, " }\n"); + break; + } + +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * data protocol compression parameters */ +static void dump_dcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case V42BIS: + if (comp_field->v42bis_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v42bis_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v42bis_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v42bis_params->nsapi_len); + if (comp_field->v42bis_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v42bis_params->nsapi_len; i++) + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v42bis_params->nsapi[i]); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v42bis_params->p0); + LOGP(DSNDCP, logl, " p1=%d;\n", + comp_field->v42bis_params->p1); + LOGP(DSNDCP, logl, " p2=%d;\n", + comp_field->v42bis_params->p2); + LOGP(DSNDCP, logl, " }\n"); + break; + case V44: + if (comp_field->v44_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v44_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v44_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v44_params->nsapi_len); + if (comp_field->v44_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v44_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v44_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " c0=%d;\n", + comp_field->v44_params->c0); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v44_params->p0); + LOGP(DSNDCP, logl, " p1t=%d;\n", + comp_field->v44_params->p1t); + LOGP(DSNDCP, logl, " p1r=%d;\n", + comp_field->v44_params->p1r); + LOGP(DSNDCP, logl, " p3t=%d;\n", + comp_field->v44_params->p3t); + LOGP(DSNDCP, logl, " p3r=%d;\n", + comp_field->v44_params->p3r); + LOGP(DSNDCP, logl, " }\n"); + break; + } +} + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl) +{ + struct gprs_sndcp_comp_field *comp_field; + int i; + int compclass; + + OSMO_ASSERT(comp_fields); + + llist_for_each_entry(comp_field, comp_fields, list) { + LOGP(DSNDCP, logl, "SNDCP-XID:\n"); + LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n"); + LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity); + LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo); + LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len); + if (comp_field->comp_len == 0) + LOGP(DSNDCP, logl, " comp[] = NULL;\n"); + for (i = 0; i < comp_field->comp_len; i++) { + LOGP(DSNDCP, logl, " comp[%d]=%d;\n", i, + comp_field->comp[i]); + } + + compclass = gprs_sndcp_get_compression_class(comp_field); + + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + dump_pcomp_params(comp_field, logl); + } else if (compclass == SNDCP_XID_DATA_COMPRESSION) { + dump_dcomp_params(comp_field, logl); + } + + LOGP(DSNDCP, logl, "}\n"); + } + +} diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..1debb2d 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid +SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid if BUILD_NAT SUBDIRS += bsc-nat bsc-nat-trie diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 74af159..45d1780 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -31,6 +31,7 @@ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -38,5 +39,5 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + -lgtp -lrt -lm diff --git a/openbsc/tests/sndcp_xid/Makefile.am b/openbsc/tests/sndcp_xid/Makefile.am new file mode 100644 index 0000000..99b9d1a --- /dev/null +++ b/openbsc/tests/sndcp_xid/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = sndcp_xid_test.ok + +noinst_PROGRAMS = sndcp_xid_test + +sndcp_xid_test_SOURCES = sndcp_xid_test.c + +sndcp_xid_test_LDADD = \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp -lrt -lm + + diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.c b/openbsc/tests/sndcp_xid/sndcp_xid_test.c new file mode 100644 index 0000000..3a33619 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.c @@ -0,0 +1,282 @@ +/* Test SNDCP-XID Encoding/Decoding */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include + +/* Test SNDCP-XID decoding with a real world sample */ +static void test_xid_decode_realworld(const void *ctx) +{ + struct llist_head *comp_fields; + int rc; + printf("Testing SNDCP XID-Decoder/Encoder (real world data)\n"); + + /* Example of a real world SNDCP-XID message */ + uint8_t xid[] = + { 0x00, 0x01, 0x00, 0x02, 0x31, 0x82, 0x02, 0x27, 0x89, 0xff, 0xe0, + 0x00, 0x0f, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, + 0x01, 0x02, 0x00, 0x03, 0x01, 0x03, 0x00, 0x04, 0x01, 0x04, 0x00, 0x05, + 0x01, 0x05, 0x00, 0x06, 0x00, 0x07, 0x01, 0x07, 0x00, 0x08, 0x01, 0x08, + 0x80, 0x00, 0x04, 0x12, 0x00, 0x40, 0x07 }; + uint8_t xid_r[512]; + + /* Parse and show contained comp fields */ + comp_fields = gprs_sndcp_parse_xid(ctx, xid, sizeof(xid), NULL); + OSMO_ASSERT(comp_fields); + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields, DSNDCP); + + /* Encode comp-fields again */ + rc = gprs_sndcp_compile_xid(xid_r,sizeof(xid_r), comp_fields); + printf("Result length=%i\n",rc); + printf("Encoded: %s\n", osmo_hexdump_nospc(xid, sizeof(xid))); + printf("Rencoded: %s\n", osmo_hexdump_nospc(xid_r, rc)); + + OSMO_ASSERT(rc == 54); + OSMO_ASSERT(memcmp(xid, xid_r, sizeof(xid)) == 0); + + /* Free comp fields */ + talloc_free(comp_fields); + + printf("\n"); +} + +/* Encode and decode test with artificial test data */ +static void test_xid_encode_decode(const void *ctx) +{ + printf("Testing SNDCP XID-Encoder/Decoder\n"); + + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_pcomp_rfc2507_params rfc2507_params; + struct gprs_sndcp_comp_field rfc2507_comp_field; + struct gprs_sndcp_pcomp_rohc_params rohc_params; + struct gprs_sndcp_comp_field rohc_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; + struct gprs_sndcp_dcomp_v44_params v44_params; + struct gprs_sndcp_comp_field v44_comp_field; + struct llist_head *comp_fields_dec; + + uint8_t xid[512]; + unsigned int xid_len = sizeof(xid); + int rc; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rfc2507_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rohc_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v44_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc1144_params.nsapi[0] = 5; + rfc1144_params.nsapi_len = 1; + + /* Setup rfc1144 operating parameters */ + rfc1144_params.s01 = 7; + + /* Setup rfc1144 compression field */ + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = 0; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc2507_params.nsapi[0] = 6; + rfc2507_params.nsapi_len = 1; + + /* Setup rfc2507 operating parameters */ + rfc2507_params.f_max_period = 256; + rfc2507_params.f_max_time = 5; + rfc2507_params.max_header = 168; + rfc2507_params.tcp_space = 15; + rfc2507_params.non_tcp_space = 15; + + /* Setup rfc2507 compression field */ + rfc2507_comp_field.p = 1; + rfc2507_comp_field.entity = 1; + rfc2507_comp_field.algo = RFC_2507; + rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3; + rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4; + rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5; + rfc2507_comp_field.comp[RFC2507_PCOMP4] = 6; + rfc2507_comp_field.comp[RFC2507_PCOMP5] = 7; + rfc2507_comp_field.comp_len = RFC2507_PCOMP_NUM; + rfc2507_comp_field.rfc2507_params = &rfc2507_params; + + /* Setup which NSAPIs shall make use of ROHC */ + rohc_params.nsapi[0] = 5; + rohc_params.nsapi[1] = 6; + rohc_params.nsapi[2] = 7; + rohc_params.nsapi[3] = 8; + rohc_params.nsapi[4] = 9; + rohc_params.nsapi[5] = 10; + rohc_params.nsapi[6] = 11; + rohc_params.nsapi[7] = 12; + rohc_params.nsapi[8] = 13; + rohc_params.nsapi[9] = 14; + rohc_params.nsapi[10] = 15; + rohc_params.nsapi_len = 11; + + /* Setup ROHC operating parameters */ + rohc_params.max_cid = 15; /* default */ + rohc_params.max_header = 168; /* default */ + rohc_params.profile[0] = ROHC_UNCOMPRESSED; + rohc_params.profile[1] = ROHC_RTP; + rohc_params.profile[2] = ROHCV2_RTP; + rohc_params.profile[3] = ROHC_UDP; + rohc_params.profile[4] = ROHCv2_UDP; + rohc_params.profile[5] = ROHC_ESP; + rohc_params.profile[6] = ROHCV2_ESP; + rohc_params.profile[7] = ROHC_IP; + rohc_params.profile[8] = ROHCV2_IP; + rohc_params.profile[9] = ROHC_LLA; + rohc_params.profile[10] = ROHC_LLA_WITH_R_MODE; + rohc_params.profile[11] = ROHC_TCP; + rohc_params.profile[12] = ROHC_RTP_UDP_LITE; + rohc_params.profile[13] = ROHCV2_RTP_UDP_LITE; + rohc_params.profile[14] = ROHC_UDP_LITE; + rohc_params.profile[15] = ROHCV2_UDP_LITE; + rohc_params.profile_len = 16; + + /* Setup ROHC compression field */ + rohc_comp_field.p = 1; + rohc_comp_field.entity = 2; + rohc_comp_field.algo = ROHC; + rohc_comp_field.comp[ROHC_PCOMP1] = 8; + rohc_comp_field.comp[ROHC_PCOMP2] = 9; + rohc_comp_field.comp_len = ROHC_PCOMP_NUM; + rohc_comp_field.rohc_params = &rohc_params; + + /* Setup which NSAPIs shall make use of v42bis */ + v42bis_params.nsapi[0] = 5; + v42bis_params.nsapi_len = 1; + + /* Setup v42bis operating parameters */ + v42bis_params.p0 = 3; + v42bis_params.p1 = 2048; + v42bis_params.p2 = 20; + + /* Setup v42bis compression field */ + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = 3; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 10; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + + /* Setup which NSAPIs shall make use of v44 */ + v44_params.nsapi[0] = 5; + v44_params.nsapi_len = 1; + + /* Setup v44 operating parameters */ + v44_params.c0 = 0x80; + v44_params.p0 = 3; + v44_params.p1t = 300; + v44_params.p1r = 300; + v44_params.p3t = 600; + v44_params.p3r = 600; + + /* Setup v44 compression field */ + v44_comp_field.p = 1; + v44_comp_field.entity = 3; + v44_comp_field.algo = V44; + v44_comp_field.comp[V44_DCOMP1] = 10; + v44_comp_field.comp[V44_DCOMP2] = 11; + v44_comp_field.comp_len = V44_DCOMP_NUM; + v44_comp_field.v44_params = &v44_params; + + /* Add compression field(s) to list */ + llist_add(&v44_comp_field.list, &comp_fields); + llist_add(&v42bis_comp_field.list, &comp_fields); + llist_add(&rfc1144_comp_field.list, &comp_fields); + llist_add(&rfc2507_comp_field.list, &comp_fields); + llist_add(&rohc_comp_field.list, &comp_fields); + printf("Test input data:\n"); + gprs_sndcp_dump_comp_fields(&comp_fields, DSNDCP); + + /* Encode SNDCP-XID fields */ + rc = gprs_sndcp_compile_xid(xid, xid_len, &comp_fields); + OSMO_ASSERT(rc > 0); + + printf("Encoded: %s (%i bytes)\n", osmo_hexdump_nospc(xid, rc), rc); + + /* Parse and show contained comp fields */ + comp_fields_dec = gprs_sndcp_parse_xid(ctx, xid, rc, NULL); + OSMO_ASSERT(comp_fields_dec); + + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields_dec, DSNDCP); + + /* Free comp fields */ + talloc_free(comp_fields_dec); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *xid_ctx; + + osmo_init_logging(&info); + + xid_ctx = talloc_named_const(NULL, 0, "xid_ctx"); + + test_xid_decode_realworld(xid_ctx); + test_xid_encode_decode(xid_ctx); + + printf("Done\n"); + + talloc_report_full(xid_ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.ok b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok new file mode 100644 index 0000000..f357282 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok @@ -0,0 +1,11 @@ +Testing SNDCP XID-Decoder/Encoder (real world data) +Decoded: +Result length=54 +Encoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 +Rencoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 + +Testing SNDCP XID-Encoder/Decoder +Test input data: +Encoded: 000100011a83010dab00208003012c012c02580258830007a000200308001402408000041200200781010c3456700040010005a80f000f82022789ffe0000f00a80000000101010002010200030103000401040005010500060007010700080108 (97 bytes) +Decoded: +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 6470ab9..85a81d6 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -129,3 +129,10 @@ cat $abs_srcdir/xid/xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([sndcp_xid]) +AT_KEYWORDS([sndcp_xid]) +cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) +AT_CLEANUP + -- To view, visit https://gerrit.osmocom.org/641 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e Gerrit-PatchSet: 15 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#27). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,447 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/27 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9a093ab..850eb42 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -19,7 +19,7 @@ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ - iu.h slhc.h + iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..fe3c4ec --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,48 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data_o, uint8_t *data_i, unsigned int len, + uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..2d70f5a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 245636b..2910c02 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,7 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 32920da..98084af 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -525,11 +547,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..4bd0076 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -143,6 +268,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +301,46 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + expnd = talloc_zero_size(msg, msg->len + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + sne->defrag.pcomp, sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } else + npdu_len = rc; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + talloc_free(expnd); + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +501,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +539,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +605,39 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; + uint8_t *compr; + uint8_t *msg_ptr; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_pcomp_compress(compr, msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); + talloc_free(compr); + return -EIO; + } else { + msgb_get(msg, msg->len); + msg_ptr = msgb_put(msg, rc); + memcpy(msg_ptr, compr, rc); + } + talloc_free(compr); +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +659,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +679,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +702,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +732,58 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + sne->defrag.pcomp, sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } else + npdu_len = rc; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + talloc_free(expnd); + return rc; } #if 0 @@ -619,3 +843,327 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + else { + return gprs_ll_xid_req(lle, NULL); + } +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive && + comp_field->rfc1144_params->nsapi_len > 0) { + LOGP(DSNDCP, LOGL_DEBUG, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, + "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, + "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..c5118cd --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,288 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int gprs_sndcp_pcomp_rfc1144_compress(uint8_t *pcomp_index, + uint8_t *data_o, uint8_t *data_i, + unsigned int len, + struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + } else + *pcomp_index = 0; + + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int gprs_sndcp_pcomp_rfc1144_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, + uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, "gprs_sndcp_pcomp_rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = gprs_sndcp_pcomp_rfc1144_expand(data_o, data_i, len, pcomp_index, + comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = gprs_sndcp_pcomp_rfc1144_compress(&pcomp_index, data_o, data_i, + len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..6e6bbfd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -314,7 +317,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 3e66978..1804280 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -33,6 +33,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 27 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: V.42bis: add sourcecode from IAXmodem (SPANDSP) In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/643 to look at the new patch set (#29). V.42bis: add sourcecode from IAXmodem (SPANDSP) V.42bis is a data compression method found in modems. It has also been specified for GPRS as data compression algorithm. The implementation has been taken from IAXmodem: https://sourceforge.net/p/iaxmodem/code/HEAD/tree/ svn checkout svn://svn.code.sf.net/p/iaxmodem/code/ iaxmodem-code Revision: r36 Change-Id: Iabedece9f97ca944a1e3f747bb073e532c4e9dca --- A openbsc/include/openbsc/v42bis.h A openbsc/include/openbsc/v42bis_private.h A openbsc/src/gprs/v42bis.c 3 files changed, 1,031 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/43/643/29 diff --git a/openbsc/include/openbsc/v42bis.h b/openbsc/include/openbsc/v42bis.h new file mode 100644 index 0000000..b947a61 --- /dev/null +++ b/openbsc/include/openbsc/v42bis.h @@ -0,0 +1,140 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005, 2011 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \page v42bis_page V.42bis modem data compression +\section v42bis_page_sec_1 What does it do? +The v.42bis specification defines a data compression scheme, to work in +conjunction with the error correction scheme defined in V.42. + +\section v42bis_page_sec_2 How does it work? +*/ + +#if !defined(_SPANDSP_V42BIS_H_) +#define _SPANDSP_V42BIS_H_ + +#define V42BIS_MIN_STRING_SIZE 6 +#define V42BIS_MAX_STRING_SIZE 250 +#define V42BIS_MIN_DICTIONARY_SIZE 512 +#define V42BIS_MAX_BITS 12 +#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ +#define V42BIS_MAX_OUTPUT_LENGTH 1024 + +enum +{ + V42BIS_P0_NEITHER_DIRECTION = 0, + V42BIS_P0_INITIATOR_RESPONDER, + V42BIS_P0_RESPONDER_INITIATOR, + V42BIS_P0_BOTH_DIRECTIONS +}; + +enum +{ + V42BIS_COMPRESSION_MODE_DYNAMIC = 0, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER +}; + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +typedef struct v42bis_state_s v42bis_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Compress a block of octets. + \param s The V.42bis context. + \param buf The data to be compressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in a compression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s); + +/*! Decompress a block of octets. + \param s The V.42bis context. + \param buf The data to be decompressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in the decompression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *s); + +/*! Set the compression mode. + \param s The V.42bis context. + \param mode One of the V.42bis compression modes - + V42BIS_COMPRESSION_MODE_DYNAMIC, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER */ +SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode); + +/*! Initialise a V.42bis context. + \param s The V.42bis context. + \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. + \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. + \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. + \param encode_handler Encode callback handler. + \param encode_user_data An opaque pointer passed to the encode callback handler. + \param max_encode_len The maximum length that should be passed to the encode handler. + \param decode_handler Decode callback handler. + \param decode_user_data An opaque pointer passed to the decode callback handler. + \param max_decode_len The maximum length that should be passed to the decode handler. + \return The V.42bis context. */ +SPAN_DECLARE(v42bis_state_t *) v42bis_init(v42bis_state_t *s, + int negotiated_p0, + int negotiated_p1, + int negotiated_p2, + put_msg_func_t encode_handler, + void *encode_user_data, + int max_encode_len, + put_msg_func_t decode_handler, + void *decode_user_data, + int max_decode_len); + +/*! Release a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s); + +/*! Free a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/openbsc/include/openbsc/v42bis_private.h b/openbsc/include/openbsc/v42bis_private.h new file mode 100644 index 0000000..2c801eb --- /dev/null +++ b/openbsc/include/openbsc/v42bis_private.h @@ -0,0 +1,127 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * private/v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(_SPANDSP_PRIVATE_V42BIS_H_) +#define _SPANDSP_PRIVATE_V42BIS_H_ + +/*! + V.42bis dictionary node. + Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used + as a "no such value" marker in this structure. +*/ +typedef struct +{ + /*! \brief The value of the octet represented by the current dictionary node */ + uint8_t node_octet; + /*! \brief The parent of this node */ + uint16_t parent; + /*! \brief The first child of this node */ + uint16_t child; + /*! \brief The next node at the same depth */ + uint16_t next; +} v42bis_dict_node_t; + +/*! + V.42bis compression or decompression. This defines the working state for a single instance + of V.42bis compression or decompression. +*/ +typedef struct +{ + /*! \brief Compression enabled. */ + int v42bis_parm_p0; + /*! \brief Compression mode. */ + int compression_mode; + /*! \brief Callback function to handle output data. */ + put_msg_func_t handler; + /*! \brief An opaque pointer passed in calls to the data handler. */ + void *user_data; + /*! \brief The maximum amount to be passed to the data handler. */ + int max_output_len; + + /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ + int transparent; + /*! \brief Next empty dictionary entry */ + uint16_t v42bis_parm_c1; + /*! \brief Current codeword size */ + uint16_t v42bis_parm_c2; + /*! \brief Threshold for codeword size change */ + uint16_t v42bis_parm_c3; + /*! \brief The current update point in the dictionary */ + uint16_t update_at; + /*! \brief The last entry matched in the dictionary */ + uint16_t last_matched; + /*! \brief The last entry added to the dictionary */ + uint16_t last_added; + /*! \brief Total number of codewords in the dictionary */ + int v42bis_parm_n2; + /*! \brief Maximum permitted string length */ + int v42bis_parm_n7; + /*! \brief The dictionary */ + v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; + + /*! \brief The octet string in progress */ + uint8_t string[V42BIS_MAX_STRING_SIZE]; + /*! \brief The current length of the octet string in progress */ + int string_length; + /*! \brief The amount of the octet string in progress which has already + been flushed out of the buffer */ + int flushed_length; + + /*! \brief Compression performance metric */ + uint16_t compression_performance; + + /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */ + uint32_t bit_buffer; + /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */ + int bit_count; + + /*! \brief The output composition buffer */ + uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH]; + /*! \brief The length of the contents of the output composition buffer */ + int output_octet_count; + + /*! \brief The current value of the escape code */ + uint8_t escape_code; + /*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */ + int escaped; +} v42bis_comp_state_t; + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +struct v42bis_state_s +{ + /*! \brief Compression state. */ + v42bis_comp_state_t compress; + /*! \brief Decompression state. */ + v42bis_comp_state_t decompress; + + /*! \brief Error and flow logging control */ + logging_state_t logging; +}; + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/openbsc/src/gprs/v42bis.c b/openbsc/src/gprs/v42bis.c new file mode 100644 index 0000000..d025ea9 --- /dev/null +++ b/openbsc/src/gprs/v42bis.c @@ -0,0 +1,764 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * v42bis.c + * + * Written by Steve Underwood + * + * Copyright (C) 2005, 2011 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. + Currently it performs the core compression and decompression functions OK. + However, a number of the bells and whistles in V.42bis are incomplete. */ + +/*! \file */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spandsp/telephony.h" +#include "spandsp/logging.h" +#include "spandsp/bit_operations.h" +#include "spandsp/async.h" +#include "spandsp/v42bis.h" + +#include "spandsp/private/logging.h" +#include "spandsp/private/v42bis.h" + +/* Fixed parameters from the spec. */ +/* Character size (bits) */ +#define V42BIS_N3 8 +/* Number of characters in the alphabet */ +#define V42BIS_N4 256 +/* Index number of first dictionary entry used to store a string */ +#define V42BIS_N5 (V42BIS_N4 + V42BIS_N6) +/* Number of control codewords */ +#define V42BIS_N6 3 +/* V.42bis/9.2 */ +#define V42BIS_ESC_STEP 51 + +/* Compreeibility monitoring parameters for assessing automated switches between + transparent and compressed mode */ +#define COMPRESSIBILITY_MONITOR (256*V42BIS_N3) +#define COMPRESSIBILITY_MONITOR_HYSTERESIS 11 + +/* Control code words in compressed mode */ +enum +{ + V42BIS_ETM = 0, /* Enter transparent mode */ + V42BIS_FLUSH = 1, /* Flush data */ + V42BIS_STEPUP = 2 /* Step up codeword size */ +}; + +/* Command codes in transparent mode */ +enum +{ + V42BIS_ECM = 0, /* Enter compression mode */ + V42BIS_EID = 1, /* Escape character in data */ + V42BIS_RESET = 2 /* Force reinitialisation */ +}; + +static __inline__ void push_octet(v42bis_comp_state_t *s, int octet) +{ + s->output_buf[s->output_octet_count++] = (uint8_t) octet; + if (s->output_octet_count >= s->max_output_len) + { + s->handler(s->user_data, s->output_buf, s->output_octet_count); + s->output_octet_count = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_octets(v42bis_comp_state_t *s, const uint8_t buf[], int len) +{ + int i; + int chunk; + + i = 0; + while ((s->output_octet_count + len - i) >= s->max_output_len) + { + chunk = s->max_output_len - s->output_octet_count; + memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); + s->handler(s->user_data, s->output_buf, s->max_output_len); + s->output_octet_count = 0; + i += chunk; + } + chunk = len - i; + if (chunk > 0) + { + memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); + s->output_octet_count += chunk; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_compressed_code(v42bis_comp_state_t *s, int code) +{ + s->bit_buffer |= code << s->bit_count; + s->bit_count += s->v42bis_parm_c2; + while (s->bit_count >= 8) + { + push_octet(s, s->bit_buffer & 0xFF); + s->bit_buffer >>= 8; + s->bit_count -= 8; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_octet_alignment(v42bis_comp_state_t *s) +{ + if ((s->bit_count & 7)) + { + s->bit_count += (8 - (s->bit_count & 7)); + while (s->bit_count >= 8) + { + push_octet(s, s->bit_buffer & 0xFF); + s->bit_buffer >>= 8; + s->bit_count -= 8; + } + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void flush_octets(v42bis_comp_state_t *s) +{ + if (s->output_octet_count > 0) + { + s->handler(s->user_data, s->output_buf, s->output_octet_count); + s->output_octet_count = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +static void dictionary_init(v42bis_comp_state_t *s) +{ + int i; + + memset(s->dict, 0, sizeof(s->dict)); + for (i = 0; i < V42BIS_N4; i++) + s->dict[i + V42BIS_N6].node_octet = i; + s->v42bis_parm_c1 = V42BIS_N5; + s->v42bis_parm_c2 = V42BIS_N3 + 1; + s->v42bis_parm_c3 = V42BIS_N4 << 1; + s->last_matched = 0; + s->update_at = 0; + s->last_added = 0; + s->bit_buffer = 0; + s->bit_count = 0; + s->flushed_length = 0; + s->string_length = 0; + s->escape_code = 0; + s->transparent = TRUE; + s->escaped = FALSE; + s->compression_performance = COMPRESSIBILITY_MONITOR; +} +/*- End of function --------------------------------------------------------*/ + +static uint16_t match_octet(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) +{ + uint16_t e; + + if (at == 0) + return octet + V42BIS_N6; + e = s->dict[at].child; + while (e) + { + if (s->dict[e].node_octet == octet) + return e; + e = s->dict[e].next; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static uint16_t add_octet_to_dictionary(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) +{ + uint16_t newx; + uint16_t next; + uint16_t e; + + newx = s->v42bis_parm_c1; + s->dict[newx].node_octet = octet; + s->dict[newx].parent = at; + s->dict[newx].child = 0; + s->dict[newx].next = s->dict[at].child; + s->dict[at].child = newx; + next = newx; + /* 6.5 Recovering a dictionary entry to use next */ + do + { + /* 6.5(a) and (b) */ + if (++next == s->v42bis_parm_n2) + next = V42BIS_N5; + } + while (s->dict[next].child); + /* 6.5(c) We need to reuse a leaf node */ + if (s->dict[next].parent) + { + /* 6.5(d) Detach the leaf node from its parent, and re-use it */ + e = s->dict[next].parent; + if (s->dict[e].child == next) + { + s->dict[e].child = s->dict[next].next; + } + else + { + e = s->dict[e].child; + while (s->dict[e].next != next) + e = s->dict[e].next; + s->dict[e].next = s->dict[next].next; + } + } + s->v42bis_parm_c1 = next; + return newx; +} +/*- End of function --------------------------------------------------------*/ + +static void send_string(v42bis_comp_state_t *s) +{ + push_octets(s, s->string, s->string_length); + s->string_length = 0; + s->flushed_length = 0; +} +/*- End of function --------------------------------------------------------*/ + +static void expand_codeword_to_string(v42bis_comp_state_t *s, uint16_t code) +{ + int i; + uint16_t p; + + /* Work out the length */ + for (i = 0, p = code; p; i++) + p = s->dict[p].parent; + s->string_length += i; + /* Now expand the known length of string */ + i = s->string_length - 1; + for (p = code; p; ) + { + s->string[i--] = s->dict[p].node_octet; + p = s->dict[p].parent; + } +} +/*- End of function --------------------------------------------------------*/ + +static void send_encoded_data(v42bis_comp_state_t *s, uint16_t code) +{ + int i; + + /* Update compressibility metric */ + /* Integrate at the compressed bit rate, and leak at the pre-compression bit rate */ + s->compression_performance += (s->v42bis_parm_c2 - s->compression_performance*s->string_length*V42BIS_N3/COMPRESSIBILITY_MONITOR); + if (s->transparent) + { + for (i = 0; i < s->string_length; i++) + { + push_octet(s, s->string[i]); + if (s->string[i] == s->escape_code) + { + push_octet(s, V42BIS_EID); + s->escape_code += V42BIS_ESC_STEP; + } + } + } + else + { + /* Allow for any escape octets in the string */ + for (i = 0; i < s->string_length; i++) + { + if (s->string[i] == s->escape_code) + s->escape_code += V42BIS_ESC_STEP; + } + /* 7.4 Encoding - we now have the longest matchable string, and will need to output the code for it. */ + while (code >= s->v42bis_parm_c3) + { + /* We need to increase the codeword size */ + /* 7.4(a) */ + push_compressed_code(s, V42BIS_STEPUP); + /* 7.4(b) */ + s->v42bis_parm_c2++; + /* 7.4(c) */ + s->v42bis_parm_c3 <<= 1; + /* 7.4(d) this might need to be repeated, so we loop */ + } + /* 7.5 Transfer - output the last state of the string */ + push_compressed_code(s, code); + } + s->string_length = 0; + s->flushed_length = 0; +} +/*- End of function --------------------------------------------------------*/ + +static void go_compressed(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + if (!s->transparent) + return; + span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to compressed mode\n"); + /* Switch out of transparent now, between codes. We need to send the octet which did not + match, just before switching. */ + if (s->last_matched) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + } + push_octet(s, s->escape_code); + push_octet(s, V42BIS_ECM); + s->bit_buffer = 0; + s->transparent = FALSE; +} +/*- End of function --------------------------------------------------------*/ + +static void go_transparent(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + if (s->transparent) + return; + span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to transparent mode\n"); + /* Switch into transparent now, between codes, and the unmatched octet should + go out in transparent mode, just below */ + if (s->last_matched) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + } + s->last_added = 0; + push_compressed_code(s, V42BIS_ETM); + push_octet_alignment(s); + s->transparent = TRUE; +} +/*- End of function --------------------------------------------------------*/ + +static void monitor_for_mode_change(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + switch (s->compression_mode) + { + case V42BIS_COMPRESSION_MODE_DYNAMIC: + /* 7.8 Data compressibility test */ + if (s->transparent) + { + if (s->compression_performance < COMPRESSIBILITY_MONITOR - COMPRESSIBILITY_MONITOR_HYSTERESIS) + { + /* 7.8.1 Transition to compressed mode */ + go_compressed(ss); + } + } + else + { + if (s->compression_performance > COMPRESSIBILITY_MONITOR) + { + /* 7.8.2 Transition to transparent mode */ + go_transparent(ss); + } + } + /* 7.8.3 Reset function - TODO */ + break; + case V42BIS_COMPRESSION_MODE_ALWAYS: + if (s->transparent) + go_compressed(ss); + break; + case V42BIS_COMPRESSION_MODE_NEVER: + if (!s->transparent) + go_transparent(ss); + break; + } +} +/*- End of function --------------------------------------------------------*/ + +static int v42bis_comp_init(v42bis_comp_state_t *s, + int p1, + int p2, + put_msg_func_t handler, + void *user_data, + int max_output_len) +{ + memset(s, 0, sizeof(*s)); + s->v42bis_parm_n2 = p1; + s->v42bis_parm_n7 = p2; + s->handler = handler; + s->user_data = user_data; + s->max_output_len = (max_output_len < V42BIS_MAX_OUTPUT_LENGTH) ? max_output_len : V42BIS_MAX_OUTPUT_LENGTH; + s->output_octet_count = 0; + dictionary_init(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int comp_exit(v42bis_comp_state_t *s) +{ + s->v42bis_parm_n2 = 0; + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *ss, const uint8_t buf[], int len) +{ + v42bis_comp_state_t *s; + int i; + uint16_t code; + + s = &ss->compress; + if (!s->v42bis_parm_p0) + { + /* Compression is off - just push the incoming data out */ + push_octets(s, buf, len); + return 0; + } + for (i = 0; i < len; ) + { + /* 6.4 Add the string to the dictionary */ + if (s->update_at) + { + if (match_octet(s, s->update_at, buf[i]) == 0) + s->last_added = add_octet_to_dictionary(s, s->update_at, buf[i]); + s->update_at = 0; + } + /* Match string */ + while (i < len) + { + code = match_octet(s, s->last_matched, buf[i]); + if (code == 0) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + if (code == s->last_added) + { + s->last_added = 0; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + s->last_matched = code; + /* 6.3(b) If the string matches a dictionary entry, and the entry is not that entry + created by the last invocation of the string matching procedure, then the + next character shall be read and appended to the string and this step + repeated. */ + s->string[s->string_length++] = buf[i++]; + /* 6.4(a) The string must not exceed N7 in length */ + if (s->string_length + s->flushed_length == s->v42bis_parm_n7) + { + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + } + monitor_for_mode_change(ss); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + int len; + + s = &ss->compress; + if (s->update_at) + return 0; + if (s->last_matched) + { + len = s->string_length; + send_encoded_data(s, s->last_matched); + s->flushed_length += len; + } + if (!s->transparent) + { + s->update_at = s->last_matched; + s->last_matched = 0; + s->flushed_length = 0; + push_compressed_code(s, V42BIS_FLUSH); + push_octet_alignment(s); + } + flush_octets(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *ss, const uint8_t buf[], int len) +{ + v42bis_comp_state_t *s; + int i; + int j; + int yyy; + uint16_t code; + uint16_t p; + uint8_t ch; + uint8_t in; + + s = &ss->decompress; + if (!s->v42bis_parm_p0) + { + /* Compression is off - just push the incoming data out */ + push_octets(s, buf, len); + return 0; + } + for (i = 0; i < len; ) + { + if (s->transparent) + { + in = buf[i]; + if (s->escaped) + { + /* Command */ + s->escaped = FALSE; + switch (in) + { + case V42BIS_ECM: + /* Enter compressed mode */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ECM\n"); + send_string(s); + s->transparent = FALSE; + s->update_at = s->last_matched; + s->last_matched = 0; + i++; + continue; + case V42BIS_EID: + /* Escape symbol */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_EID\n"); + in = s->escape_code; + s->escape_code += V42BIS_ESC_STEP; + break; + case V42BIS_RESET: + /* Reset dictionary */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_RESET\n"); + /* TODO: */ + send_string(s); + dictionary_init(s); + i++; + continue; + default: + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_???? - %" PRIu32 "\n", in); + return -1; + } + } + else if (in == s->escape_code) + { + s->escaped = TRUE; + i++; + continue; + } + + yyy = TRUE; + for (j = 0; j < 2 && yyy; j++) + { + if (s->update_at) + { + if (match_octet(s, s->update_at, in) == 0) + s->last_added = add_octet_to_dictionary(s, s->update_at, in); + s->update_at = 0; + } + + code = match_octet(s, s->last_matched, in); + if (code == 0) + { + s->update_at = s->last_matched; + send_string(s); + s->last_matched = 0; + } + else if (code == s->last_added) + { + s->last_added = 0; + send_string(s); + s->last_matched = 0; + } + else + { + s->last_matched = code; + s->string[s->string_length++] = in; + if (s->string_length + s->flushed_length == s->v42bis_parm_n7) + { + send_string(s); + s->last_matched = 0; + } + i++; + yyy = FALSE; + } + } + } + else + { + /* Get code from input */ + while (s->bit_count < s->v42bis_parm_c2 && i < len) + { + s->bit_buffer |= buf[i++] << s->bit_count; + s->bit_count += 8; + } + if (s->bit_count < s->v42bis_parm_c2) + continue; + code = s->bit_buffer & ((1 << s->v42bis_parm_c2) - 1); + s->bit_buffer >>= s->v42bis_parm_c2; + s->bit_count -= s->v42bis_parm_c2; + + if (code < V42BIS_N6) + { + /* We have a control code. */ + switch (code) + { + case V42BIS_ETM: + /* Enter transparent mode */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ETM\n"); + s->bit_count = 0; + s->transparent = TRUE; + s->last_matched = 0; + s->last_added = 0; + break; + case V42BIS_FLUSH: + /* Flush signal */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_FLUSH\n"); + s->bit_count = 0; + break; + case V42BIS_STEPUP: + /* Increase code word size */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_STEPUP\n"); + s->v42bis_parm_c2++; + s->v42bis_parm_c3 <<= 1; + if (s->v42bis_parm_c2 > (s->v42bis_parm_n2 >> 3)) + return -1; + break; + } + continue; + } + /* Regular codeword */ + if (code == s->v42bis_parm_c1) + return -1; + expand_codeword_to_string(s, code); + if (s->update_at) + { + ch = s->string[0]; + if ((p = match_octet(s, s->update_at, ch)) == 0) + { + s->last_added = add_octet_to_dictionary(s, s->update_at, ch); + if (code == s->v42bis_parm_c1) + return -1; + } + else if (p == s->last_added) + { + s->last_added = 0; + } + } + s->update_at = ((s->string_length + s->flushed_length) == s->v42bis_parm_n7) ? 0 : code; + /* Allow for any escapes which may be in this string */ + for (j = 0; j < s->string_length; j++) + { + if (s->string[j] == s->escape_code) + s->escape_code += V42BIS_ESC_STEP; + } + send_string(s); + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + int len; + + s = &ss->decompress; + len = s->string_length; + send_string(s); + s->flushed_length += len; + flush_octets(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode) +{ + s->compress.compression_mode = mode; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(v42bis_state_t *) v42bis_init(v42bis_state_t *s, + int negotiated_p0, + int negotiated_p1, + int negotiated_p2, + put_msg_func_t encode_handler, + void *encode_user_data, + int max_encode_len, + put_msg_func_t decode_handler, + void *decode_user_data, + int max_decode_len) +{ + int ret; + + if (negotiated_p1 < V42BIS_MIN_DICTIONARY_SIZE || negotiated_p1 > 65535) + return NULL; + if (negotiated_p2 < V42BIS_MIN_STRING_SIZE || negotiated_p2 > V42BIS_MAX_STRING_SIZE) + return NULL; + if (s == NULL) + { + if ((s = (v42bis_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + span_log_init(&s->logging, SPAN_LOG_NONE, NULL); + span_log_set_protocol(&s->logging, "V.42bis"); + + if ((ret = v42bis_comp_init(&s->compress, negotiated_p1, negotiated_p2, encode_handler, encode_user_data, max_encode_len))) + return NULL; + if ((ret = v42bis_comp_init(&s->decompress, negotiated_p1, negotiated_p2, decode_handler, decode_user_data, max_decode_len))) + { + comp_exit(&s->compress); + return NULL; + } + s->compress.v42bis_parm_p0 = negotiated_p0 & 2; + s->decompress.v42bis_parm_p0 = negotiated_p0 & 1; + + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s) +{ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s) +{ + comp_exit(&s->compress); + comp_exit(&s->decompress); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ -- To view, visit https://gerrit.osmocom.org/643 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iabedece9f97ca944a1e3f747bb073e532c4e9dca Gerrit-PatchSet: 29 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/803 to look at the new patch set (#2). SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 629 insertions(+), 42 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/03/803/2 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9bea689..e21b485 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -20,7 +20,7 @@ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h v42bis.h \ - v42bis_private.h + v42bis_private.h gprs_sndcp_dcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..9a32e9e --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,55 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data_o, uint8_t *data_i, unsigned int len, + uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 2d70f5a..12d918e 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index f479d56..98abb3d 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,8 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c \ + gprs_sndcp_dcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4bd0076..11d611d 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -270,7 +271,8 @@ uint8_t *npdu; int npdu_len; int rc; - uint8_t *expnd; + uint8_t *hdr_expnd = NULL; + uint8_t *data_expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -314,18 +316,34 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - expnd = talloc_zero_size(msg, msg->len + MAX_HDRDECOMPR_INCR); - rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + /* Apply data decompression */ + data_expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC); + rc = gprs_sndcp_dcomp_expand(data_expnd, npdu, npdu_len, + sne->defrag.dcomp, sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data decompression failed!\n"); + talloc_free(data_expnd); + return -EIO; + } + + /* Apply header decompression */ + hdr_expnd = talloc_zero_size(msg, rc + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(hdr_expnd, data_expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return -EIO; - } else - npdu_len = rc; + } + + /* Modify npu length, hdr_expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + #if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + debug_ip_packet(hdr_expnd, npdu_len, 1, "defrag_segments()"); DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, " \n"); @@ -333,9 +351,10 @@ /* Hand off packet to gtp */ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); + sne->nsapi, msg, npdu_len, hdr_expnd); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return rc; } @@ -608,7 +627,8 @@ uint8_t pcomp = 0; uint8_t dcomp = 0; int rc; - uint8_t *compr; + uint8_t *hdr_compr = NULL; + uint8_t *data_compr = NULL; uint8_t *msg_ptr; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ @@ -620,19 +640,34 @@ DEBUGP(DSNDCP, "===================================================\n"); debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); #endif - compr = talloc_zero_size(msg, msg->len); - rc = gprs_sndcp_pcomp_compress(compr, msg->data, msg->len, &pcomp, + /* Apply header compression */ + hdr_compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_pcomp_compress(hdr_compr, msg->data, msg->len, &pcomp, lle->llme->comp.proto, nsapi); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); - talloc_free(compr); + talloc_free(hdr_compr); return -EIO; - } else { - msgb_get(msg, msg->len); - msg_ptr = msgb_put(msg, rc); - memcpy(msg_ptr, compr, rc); } - talloc_free(compr); + + /* Apply data compression */ + data_compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_dcomp_compress(data_compr, hdr_compr, rc, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); + talloc_free(hdr_compr); + talloc_free(data_compr); + return -EIO; + } + + /* Copy results back to msg buffer */ + msgb_get(msg, msg->len); + msg_ptr = msgb_put(msg, rc); + memcpy(msg_ptr, data_compr, rc); + + talloc_free(hdr_compr); + talloc_free(data_compr); #if DEBUG_IP_PACKETS == 1 DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); @@ -703,7 +738,8 @@ uint16_t npdu_num __attribute__((unused)); int npdu_len; int rc; - uint8_t *expnd; + uint8_t *hdr_expnd = NULL; + uint8_t *data_expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -761,18 +797,35 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); - rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + + /* Apply data decompression */ + data_expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC); + rc = gprs_sndcp_dcomp_expand(data_expnd, npdu, npdu_len, + sne->defrag.dcomp, sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data decompression failed!\n"); + talloc_free(data_expnd); + return -EIO; + } + + /* Apply header decompression */ + hdr_expnd = talloc_zero_size(msg, rc + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(hdr_expnd, data_expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return -EIO; - } else - npdu_len = rc; + } + + /* Modify npu length, hdr_expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + #if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + debug_ip_packet(hdr_expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, " \n"); @@ -780,9 +833,10 @@ /* Hand off packet to gtp */ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); + sne->nsapi, msg, npdu_len, hdr_expnd); - talloc_free(expnd); + talloc_free(data_expnd); + talloc_free(hdr_expnd); return rc; } @@ -851,8 +905,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -868,6 +925,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -977,13 +1051,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + LOGP(DSNDCP, LOGL_DEBUG, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..b01a852 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,359 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void gprs_sndcp_dcomp_v42bis_reset(v42bis_state_t *comp) +{ + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, + "Resetting compression entity (%p), p0=%d, p1=%d, p2=%d ...\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int gprs_sndcp_dcomp_v42bis_compress(uint8_t *pcomp_index, + uint8_t *data_o, uint8_t *data_i, + unsigned int len, + v42bis_state_t *comp) +{ + uint8_t *data_c; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Reset V.42bis compression state */ + gprs_sndcp_dcomp_v42bis_reset(comp); + + /* Run compressor */ + data_c = talloc_zero_size(NULL, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_c; + compressed_data.buf_pointer = data_c; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data_i, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + memcpy(data_o, data_i, len); + talloc_free(data_c); + return len; + } + + *pcomp_index = 1; + memcpy(data_o, data_c, compressed_data.len); + talloc_free(data_c); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int gprs_sndcp_dcomp_v42bis_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, + uint8_t pcomp_index, + v42bis_state_t *comp) +{ + int rc; + struct v42bis_output_buffer uncompressed_data; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Reset V.42bis compression state */ + gprs_sndcp_dcomp_v42bis_reset(comp); + + /* Decompress packet */ + uncompressed_data.buf = data_o; + uncompressed_data.buf_pointer = data_o; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = gprs_sndcp_dcomp_v42bis_expand(data_o, data_i, len, pcomp_index, + comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = gprs_sndcp_dcomp_v42bis_compress(&pcomp_index, data_o, data_i, + len, comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 894ce84..f01798b 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -297,6 +297,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 4d4431e..48b99b2 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -36,6 +36,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/644 to look at the new patch set (#35). V.42bis: integration and unit test - Edit previously committed V.42bis implementation to function outside IAXmodem. - Add unit test to verify the correct function of V.42bis Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h M openbsc/include/openbsc/v42bis.h M openbsc/include/openbsc/v42bis_private.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/v42bis.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/testsuite.at A openbsc/tests/v42bis/Makefile.am A openbsc/tests/v42bis/v42bis_test.c A openbsc/tests/v42bis/v42bis_test.ok 14 files changed, 1,144 insertions(+), 29 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/44/644/35 -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 35 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: RFC1144: add slhc code from linux kernel In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/634 to look at the new patch set (#15). RFC1144: add slhc code from linux kernel SLHC is an Implementation of RFC1144 TCP/IP header compression. We will need RFC1144 compression to compress GPRS TCP/IP traffic. The implementation pushed with this commit was taken from: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git commit 29b4817d4018df78086157ea3a55c1d9424a7cfc Change-Id: Ied69c143678dc4a64cecc671f5c4dfebe19d8519 --- A openbsc/include/openbsc/slhc_vj.h A openbsc/src/gprs/slhc.c 2 files changed, 927 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/34/634/15 diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc_vj.h new file mode 100644 index 0000000..8716d59 --- /dev/null +++ b/openbsc/include/openbsc/slhc_vj.h @@ -0,0 +1,183 @@ +#ifndef _SLHC_H +#define _SLHC_H +/* + * Definitions for tcp compression routines. + * + * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van at helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens at ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation + * + * - Feb 1991 Bill_Simpson at um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowledgment, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + + +#include +#include + +/* SLIP compression masks for len/vers byte */ +#define SL_TYPE_IP 0x40 +#define SL_TYPE_UNCOMPRESSED_TCP 0x70 +#define SL_TYPE_COMPRESSED_TCP 0x80 +#define SL_TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + +/* + * data type and sizes conversion assumptions: + * + * VJ code KA9Q style generic + * u_char byte_t unsigned char 8 bits + * u_short int16 unsigned short 16 bits + * u_int int16 unsigned short 16 bits + * u_long unsigned long unsigned long 32 bits + * int int32 long 32 bits + */ + +typedef __u8 byte_t; +typedef __u32 int32; + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + byte_t cs_this; /* connection id number (xmit) */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; + unsigned char cs_ipopt[64]; + unsigned char cs_tcpopt[64]; + int cs_hsize; +}; +#define NULLSLSTATE (struct cstate *)0 + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct slcompress { + struct cstate *tstate; /* transmit connection states (array)*/ + struct cstate *rstate; /* receive connection states (array)*/ + + byte_t tslot_limit; /* highest transmit slot id (0-l)*/ + byte_t rslot_limit; /* highest receive slot id (0-l)*/ + + byte_t xmit_oldest; /* oldest xmit in ring */ + byte_t xmit_current; /* most recent xmit id */ + byte_t recv_current; /* most recent rcvd id */ + + byte_t flags; +#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ + + int32 sls_o_nontcp; /* outbound non-TCP packets */ + int32 sls_o_tcp; /* outbound TCP packets */ + int32 sls_o_uncompressed; /* outbound uncompressed packets */ + int32 sls_o_compressed; /* outbound compressed packets */ + int32 sls_o_searches; /* searches for connection state */ + int32 sls_o_misses; /* times couldn't find conn. state */ + + int32 sls_i_uncompressed; /* inbound uncompressed packets */ + int32 sls_i_compressed; /* inbound compressed packets */ + int32 sls_i_error; /* inbound error packets */ + int32 sls_i_tossed; /* inbound packets tossed because of error */ + + int32 sls_i_runt; + int32 sls_i_badcheck; +}; +#define NULLSLCOMPR (struct slcompress *)0 + +/* In slhc.c: */ +struct slcompress *slhc_init(int rslots, int tslots); +void slhc_free(struct slcompress *comp); + +int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid); +int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_toss(struct slcompress *comp); + +#endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c new file mode 100644 index 0000000..27ed252 --- /dev/null +++ b/openbsc/src/gprs/slhc.c @@ -0,0 +1,744 @@ +/* + * Routines to compress and uncompress tcp packets (for transmission + * over low speed serial lines). + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van at helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens at ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation (from 1.19) + * PPP.05 02-15-90 [ks] + * PPP.08 05-02-90 [ks] use PPP protocol field to signal compression + * PPP.15 09-90 [ks] improve mbuf handling + * PPP.16 11-02 [karn] substantially rewritten to use NOS facilities + * + * - Feb 1991 Bill_Simpson at um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + * - Jul 1994 Dmitry Gorodchanin + * Fixes for memory leaks. + * - Oct 1994 Dmitry Gorodchanin + * Modularization. + * - Jan 1995 Bjorn Ekwall + * Use ip_fast_csum from ip.h + * - July 1995 Christos A. Polyzols + * Spotted bug in tcp option checking + * + * + * This module is a difficult issue. It's clearly inet code but it's also clearly + * driver code belonging close to PPP and SLIP + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_INET +/* Entire module is for IP only */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned char *encode(unsigned char *cp, unsigned short n); +static long decode(unsigned char **cpp); +static unsigned char * put16(unsigned char *cp, unsigned short x); +static unsigned short pull16(unsigned char **cpp); + +/* Allocate compression data structure + * slots must be in range 0 to 255 (zero meaning no compression) + * Returns pointer to structure or ERR_PTR() on error. + */ +struct slcompress * +slhc_init(int rslots, int tslots) +{ + register short i; + register struct cstate *ts; + struct slcompress *comp; + + if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) + return ERR_PTR(-EINVAL); + + comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + if (! comp) + goto out_fail; + + if (rslots > 0) { + size_t rsize = rslots * sizeof(struct cstate); + comp->rstate = kzalloc(rsize, GFP_KERNEL); + if (! comp->rstate) + goto out_free; + comp->rslot_limit = rslots - 1; + } + + if (tslots > 0) { + size_t tsize = tslots * sizeof(struct cstate); + comp->tstate = kzalloc(tsize, GFP_KERNEL); + if (! comp->tstate) + goto out_free2; + comp->tslot_limit = tslots - 1; + } + + comp->xmit_oldest = 0; + comp->xmit_current = 255; + comp->recv_current = 255; + /* + * don't accept any packets with implicit index until we get + * one with an explicit index. Otherwise the uncompress code + * will try to use connection 255, which is almost certainly + * out of range + */ + comp->flags |= SLF_TOSS; + + if ( tslots > 0 ) { + ts = comp->tstate; + for(i = comp->tslot_limit; i > 0; --i){ + ts[i].cs_this = i; + ts[i].next = &(ts[i - 1]); + } + ts[0].next = &(ts[comp->tslot_limit]); + ts[0].cs_this = 0; + } + return comp; + +out_free2: + kfree(comp->rstate); +out_free: + kfree(comp); +out_fail: + return ERR_PTR(-ENOMEM); +} + + +/* Free a compression data structure */ +void +slhc_free(struct slcompress *comp) +{ + if ( comp == NULLSLCOMPR ) + return; + + if ( comp->tstate != NULLSLSTATE ) + kfree( comp->tstate ); + + if ( comp->rstate != NULLSLSTATE ) + kfree( comp->rstate ); + + kfree( comp ); +} + + +/* Put a short in host order into a char array in network order */ +static inline unsigned char * +put16(unsigned char *cp, unsigned short x) +{ + *cp++ = x >> 8; + *cp++ = x; + + return cp; +} + + +/* Encode a number */ +static unsigned char * +encode(unsigned char *cp, unsigned short n) +{ + if(n >= 256 || n == 0){ + *cp++ = 0; + cp = put16(cp,n); + } else { + *cp++ = n; + } + return cp; +} + +/* Pull a 16-bit integer in host order from buffer in network byte order */ +static unsigned short +pull16(unsigned char **cpp) +{ + short rval; + + rval = *(*cpp)++; + rval <<= 8; + rval |= *(*cpp)++; + return rval; +} + +/* Decode a number */ +static long +decode(unsigned char **cpp) +{ + register int x; + + x = *(*cpp)++; + if(x == 0){ + return pull16(cpp) & 0xffff; /* pull16 returns -1 on error */ + } else { + return x & 0xff; /* -1 if PULLCHAR returned error */ + } +} + +/* + * icp and isize are the original packet. + * ocp is a place to put a copy if necessary. + * cpp is initially a pointer to icp. If the copy is used, + * change it to ocp. + */ + +int +slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid) +{ + register struct cstate *ocs = &(comp->tstate[comp->xmit_oldest]); + register struct cstate *lcs = ocs; + register struct cstate *cs = lcs->next; + register unsigned long deltaS, deltaA; + register short changes = 0; + int hlen; + unsigned char new_seq[16]; + register unsigned char *cp = new_seq; + struct iphdr *ip; + struct tcphdr *th, *oth; + __sum16 csum; + + + /* + * Don't play with runt packets. + */ + + if(isizeprotocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { + /* Send as regular IP */ + if(ip->protocol != IPPROTO_TCP) + comp->sls_o_nontcp++; + else + comp->sls_o_tcp++; + return isize; + } + /* Extract TCP header */ + + th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); + hlen = ip->ihl*4 + th->doff*4; + + /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or + * some other control bit is set). Also uncompressible if + * it's a runt. + */ + if(hlen > isize || th->syn || th->fin || th->rst || + ! (th->ack)){ + /* TCP connection stuff; send as regular IP */ + comp->sls_o_tcp++; + return isize; + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way, + * we need to locate (or create) the connection state. + * + * States are kept in a circularly linked list with + * xmit_oldest pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + for ( ; ; ) { + if( ip->saddr == cs->cs_ip.saddr + && ip->daddr == cs->cs_ip.daddr + && th->source == cs->cs_tcp.source + && th->dest == cs->cs_tcp.dest) + goto found; + + /* if current equal oldest, at end of list */ + if ( cs == ocs ) + break; + lcs = cs; + cs = cs->next; + comp->sls_o_searches++; + } + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * xmit_oldest to update the lru linkage. + */ + comp->sls_o_misses++; + comp->xmit_oldest = lcs->cs_this; + goto uncompressed; + +found: + /* + * Found it -- move to the front on the connection list. + */ + if(lcs == ocs) { + /* found at most recently used */ + } else if (cs == ocs) { + /* found at least recently used */ + comp->xmit_oldest = lcs->cs_this; + } else { + /* more than 2 elements */ + lcs->next = cs->next; + cs->next = ocs->next; + ocs->next = cs; + } + + /* + * Make sure that only what we expect to change changed. + * Check the following: + * IP protocol version, header length & type of service. + * The "Don't fragment" bit. + * The time-to-live field. + * The TCP header length. + * IP options, if any. + * TCP options, if any. + * If any of these things are different between the previous & + * current datagram, we send the current datagram `uncompressed'. + */ + oth = &cs->cs_tcp; + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl + || ip->tos != cs->cs_ip.tos + || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) + || ip->ttl != cs->cs_ip.ttl + || th->doff != cs->cs_tcp.doff + || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) + || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if(th->urg){ + deltaS = ntohs(th->urg_ptr); + cp = encode(cp,deltaS); + changes |= NEW_U; + } else if(th->urg_ptr != oth->urg_ptr){ + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + cp = encode(cp,deltaS); + changes |= NEW_W; + } + if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ + if(deltaA > 0x0000ffff) + goto uncompressed; + cp = encode(cp,deltaA); + changes |= NEW_A; + } + if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ + if(deltaS > 0x0000ffff) + goto uncompressed; + cp = encode(cp,deltaS); + changes |= NEW_S; + } + + switch(changes){ + case 0: /* Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if(ip->tot_len != cs->cs_ip.tot_len && + ntohs(cs->cs_ip.tot_len) == hlen) + break; + goto uncompressed; + case SPECIAL_I: + case SPECIAL_D: + /* actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + case NEW_S|NEW_A: + if(deltaS == deltaA && + deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + case NEW_S: + if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + } + deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); + if(deltaS != 1){ + cp = encode(cp,deltaS); + changes |= NEW_I; + } + if(th->psh) + changes |= TCP_PUSH_BIT; + /* Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + csum = th->check; + memcpy(&cs->cs_ip,ip,20); + memcpy(&cs->cs_tcp,th,20); + /* We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. + */ + deltaS = cp - new_seq; + if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ + cp = ocp; + *cpp = ocp; + *cp++ = changes | NEW_C; + *cp++ = cs->cs_this; + comp->xmit_current = cs->cs_this; + } else { + cp = ocp; + *cpp = ocp; + *cp++ = changes; + } + *(__sum16 *)cp = csum; + cp += 2; +/* deltaS is now the size of the change section of the compressed header */ + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ + memcpy(cp+deltaS,icp+hlen,isize-hlen); + comp->sls_o_compressed++; + ocp[0] |= SL_TYPE_COMPRESSED_TCP; + return isize - hlen + deltaS + (cp - ocp); + + /* Update connection state cs & send uncompressed packet (i.e., + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + memcpy(&cs->cs_ip,ip,20); + memcpy(&cs->cs_tcp,th,20); + if (ip->ihl > 5) + memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4); + if (th->doff > 5) + memcpy(cs->cs_tcpopt, th+1, ((th->doff) - 5) * 4); + comp->xmit_current = cs->cs_this; + comp->sls_o_uncompressed++; + memcpy(ocp, icp, isize); + *cpp = ocp; + ocp[9] = cs->cs_this; + ocp[0] |= SL_TYPE_UNCOMPRESSED_TCP; + return isize; +} + + +int +slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) +{ + register int changes; + long x; + register struct tcphdr *thp; + register struct iphdr *ip; + register struct cstate *cs; + int len, hdrlen; + unsigned char *cp = icp; + + /* We've got a compressed packet; read the change byte */ + comp->sls_i_compressed++; + if(isize < 3){ + comp->sls_i_error++; + return 0; + } + changes = *cp++; + if(changes & NEW_C){ + /* Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + x = *cp++; /* Read conn index */ + if(x < 0 || x > comp->rslot_limit) + goto bad; + + comp->flags &=~ SLF_TOSS; + comp->recv_current = x; + } else { + /* this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. */ + if(comp->flags & SLF_TOSS){ + comp->sls_i_tossed++; + return 0; + } + } + cs = &comp->rstate[comp->recv_current]; + thp = &cs->cs_tcp; + ip = &cs->cs_ip; + + thp->check = *(__sum16 *)cp; + cp += 2; + + thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0; +/* + * we can use the same number for the length of the saved header and + * the current one, because the packet wouldn't have been sent + * as compressed unless the options were the same as the previous one + */ + + hdrlen = ip->ihl * 4 + thp->doff * 4; + + switch(changes & SPECIALS_MASK){ + case SPECIAL_I: /* Echoed terminal traffic */ + { + register short i; + i = ntohs(ip->tot_len) - hdrlen; + thp->ack_seq = htonl( ntohl(thp->ack_seq) + i); + thp->seq = htonl( ntohl(thp->seq) + i); + } + break; + + case SPECIAL_D: /* Unidirectional data */ + thp->seq = htonl( ntohl(thp->seq) + + ntohs(ip->tot_len) - hdrlen); + break; + + default: + if(changes & NEW_U){ + thp->urg = 1; + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->urg_ptr = htons(x); + } else + thp->urg = 0; + if(changes & NEW_W){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->window = htons( ntohs(thp->window) + x); + } + if(changes & NEW_A){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->ack_seq = htonl( ntohl(thp->ack_seq) + x); + } + if(changes & NEW_S){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->seq = htonl( ntohl(thp->seq) + x); + } + break; + } + if(changes & NEW_I){ + if((x = decode(&cp)) == -1) { + goto bad; + } + ip->id = htons (ntohs (ip->id) + x); + } else + ip->id = htons (ntohs (ip->id) + 1); + + /* + * At this point, cp points to the first byte of data in the + * packet. Put the reconstructed TCP and IP headers back on the + * packet. Recalculate IP checksum (but not TCP checksum). + */ + + len = isize - (cp - icp); + if (len < 0) + goto bad; + len += hdrlen; + ip->tot_len = htons(len); + ip->check = 0; + + memmove(icp + hdrlen, cp, len - hdrlen); + + cp = icp; + memcpy(cp, ip, 20); + cp += 20; + + if (ip->ihl > 5) { + memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4); + cp += (ip->ihl - 5) * 4; + } + + put_unaligned(ip_fast_csum(icp, ip->ihl), + &((struct iphdr *)icp)->check); + + memcpy(cp, thp, 20); + cp += 20; + + if (thp->doff > 5) { + memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4); + cp += ((thp->doff) - 5) * 4; + } + + return len; +bad: + comp->sls_i_error++; + return slhc_toss( comp ); +} + + +int +slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +{ + register struct cstate *cs; + unsigned ihl; + + unsigned char index; + + if(isize < 20) { + /* The packet is shorter than a legal IP header */ + comp->sls_i_runt++; + return slhc_toss( comp ); + } + /* Peek at the IP header's IHL field to find its length */ + ihl = icp[0] & 0xf; + if(ihl < 20 / 4){ + /* The IP header length field is too small */ + comp->sls_i_runt++; + return slhc_toss( comp ); + } + index = icp[9]; + icp[9] = IPPROTO_TCP; + + if (ip_fast_csum(icp, ihl)) { + /* Bad IP header checksum; discard */ + comp->sls_i_badcheck++; + return slhc_toss( comp ); + } + if(index > comp->rslot_limit) { + comp->sls_i_error++; + return slhc_toss(comp); + } + + /* Update local state */ + cs = &comp->rstate[comp->recv_current = index]; + comp->flags &=~ SLF_TOSS; + memcpy(&cs->cs_ip,icp,20); + memcpy(&cs->cs_tcp,icp + ihl*4,20); + if (ihl > 5) + memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); + if (cs->cs_tcp.doff > 5) + memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); + cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; + /* Put headers back on packet + * Neither header checksum is recalculated + */ + comp->sls_i_uncompressed++; + return isize; +} + +int +slhc_toss(struct slcompress *comp) +{ + if ( comp == NULLSLCOMPR ) + return 0; + + comp->flags |= SLF_TOSS; + return 0; +} + +#else /* CONFIG_INET */ + +int +slhc_toss(struct slcompress *comp) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); + return -EINVAL; +} +int +slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); + return -EINVAL; +} +int +slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); + return -EINVAL; +} + +int +slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); + return -EINVAL; +} + +void +slhc_free(struct slcompress *comp) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); +} +struct slcompress * +slhc_init(int rslots, int tslots) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); + return NULL; +} + +#endif /* CONFIG_INET */ + +/* VJ header compression */ +EXPORT_SYMBOL(slhc_init); +EXPORT_SYMBOL(slhc_free); +EXPORT_SYMBOL(slhc_remember); +EXPORT_SYMBOL(slhc_compress); +EXPORT_SYMBOL(slhc_uncompress); +EXPORT_SYMBOL(slhc_toss); + +MODULE_LICENSE("Dual BSD/GPL"); -- To view, visit https://gerrit.osmocom.org/634 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ied69c143678dc4a64cecc671f5c4dfebe19d8519 Gerrit-PatchSet: 15 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:54:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 11:54:57 +0000 Subject: [PATCH] openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/635 to look at the new patch set (#17). RFC1144: integration and unit-test The previously pushed slhc implementation has been modified to compile and function outside of the kernel. Also debug log messages were added and datatypes ware matched. The implementation is now ready to be used Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h R openbsc/include/openbsc/slhc.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/slhc.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/slhc/Makefile.am A openbsc/tests/slhc/slhc_test.c A openbsc/tests/slhc/slhc_test.ok M openbsc/tests/testsuite.at 14 files changed, 550 insertions(+), 91 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/635/17 diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 8ce3b70..e75b9eb 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -83,6 +83,7 @@ tests/mm_auth/mm_auth_test tests/xid/xid_test tests/sndcp_xid/sndcp_xid_test +tests/slhc/slhc_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 9dc2f8d..cebabdc 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -232,6 +232,7 @@ tests/mm_auth/Makefile tests/xid/Makefile tests/sndcp_xid/Makefile + tests/slhc/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index a5ba3ef..9a093ab 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -19,7 +19,7 @@ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ - iu.h + iu.h slhc.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 43ebb19..90ddca5 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -29,6 +29,7 @@ DBSSGP, DLLC, DSNDCP, + DSLHC, DNAT, DCTRL, DSMPP, diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc.h similarity index 97% rename from openbsc/include/openbsc/slhc_vj.h rename to openbsc/include/openbsc/slhc.h index 8716d59..cd5a47c 100644 --- a/openbsc/include/openbsc/slhc_vj.h +++ b/openbsc/include/openbsc/slhc.h @@ -171,7 +171,8 @@ #define NULLSLCOMPR (struct slcompress *)0 /* In slhc.c: */ -struct slcompress *slhc_init(int rslots, int tslots); +struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); + void slhc_free(struct slcompress *comp); int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, @@ -180,4 +181,7 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); int slhc_toss(struct slcompress *comp); +void slhc_i_status(struct slcompress *comp); +void slhc_o_status(struct slcompress *comp); + #endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index fa4a3dd..245636b 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -26,7 +26,8 @@ sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c + oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ + slhc.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..894ce84 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -292,6 +292,11 @@ .description = "SCCP User Adaptation (SUA)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DSLHC] = { + .name = "DSLHC", + .description = "RFC1144 TCP/IP Header compression (SLHC)", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c index 27ed252..cbdf8db 100644 --- a/openbsc/src/gprs/slhc.c +++ b/openbsc/src/gprs/slhc.c @@ -50,61 +50,77 @@ * driver code belonging close to PPP and SLIP */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef CONFIG_INET -/* Entire module is for IP only */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#define ERR_PTR(x) x + static unsigned char *encode(unsigned char *cp, unsigned short n); static long decode(unsigned char **cpp); static unsigned char * put16(unsigned char *cp, unsigned short x); static unsigned short pull16(unsigned char **cpp); +/* Replacement for kernel space function ip_fast_csum() */ +static uint16_t ip_fast_csum(uint8_t *iph, int ihl) +{ + int i; + uint16_t temp; + uint32_t accumulator = 0xFFFF; + + for(i=0;i0xFFFF) + { + accumulator++; + accumulator&=0xFFFF; + } + } + + return (uint16_t)(htons(~accumulator)&0xFFFF); +} + +/* Replacement for kernel space function put_unaligned() */ +static void put_unaligned(uint16_t val, void *ptr) +{ + memcpy(ptr,&val,sizeof(val)); +} + + /* Allocate compression data structure * slots must be in range 0 to 255 (zero meaning no compression) * Returns pointer to structure or ERR_PTR() on error. */ struct slcompress * -slhc_init(int rslots, int tslots) +slhc_init(const void *ctx, int rslots, int tslots) { register short i; register struct cstate *ts; struct slcompress *comp; if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) - return ERR_PTR(-EINVAL); + return NULL; - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = (struct slcompress *)talloc_zero_size(ctx,sizeof(struct slcompress)); if (! comp) goto out_fail; if (rslots > 0) { size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = kzalloc(rsize, GFP_KERNEL); + comp->rstate = (struct cstate *) talloc_zero_size(ctx, rsize); if (! comp->rstate) goto out_free; comp->rslot_limit = rslots - 1; @@ -112,7 +128,7 @@ if (tslots > 0) { size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = kzalloc(tsize, GFP_KERNEL); + comp->tstate = (struct cstate *) talloc_zero_size(ctx, tsize); if (! comp->tstate) goto out_free2; comp->tslot_limit = tslots - 1; @@ -141,11 +157,11 @@ return comp; out_free2: - kfree(comp->rstate); + talloc_free(comp->rstate); out_free: - kfree(comp); + talloc_free(comp); out_fail: - return ERR_PTR(-ENOMEM); + return NULL; } @@ -153,16 +169,18 @@ void slhc_free(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_free(): Freeing compression states...\n"); + if ( comp == NULLSLCOMPR ) return; if ( comp->tstate != NULLSLSTATE ) - kfree( comp->tstate ); + talloc_free(comp->tstate ); if ( comp->rstate != NULLSLSTATE ) - kfree( comp->rstate ); + talloc_free( comp->rstate ); - kfree( comp ); + talloc_free( comp ); } @@ -187,6 +205,8 @@ } else { *cp++ = n; } + + DEBUGP(DSLHC, "encode(): n=%04x\n",n); return cp; } @@ -256,6 +276,7 @@ comp->sls_o_nontcp++; else comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Not a TCP packat, will not touch...\n"); return isize; } /* Extract TCP header */ @@ -271,6 +292,7 @@ ! (th->ack)){ /* TCP connection stuff; send as regular IP */ comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Packet is part of a TCP connection, will not touch...\n"); return isize; } /* @@ -287,6 +309,9 @@ * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ + + DEBUGP(DSLHC, "slhc_compress(): Compressible packet detected!\n"); + for ( ; ; ) { if( ip->saddr == cs->cs_ip.saddr && ip->daddr == cs->cs_ip.daddr @@ -310,11 +335,14 @@ * state points to the newest and we only need to set * xmit_oldest to update the lru linkage. */ + + DEBUGP(DSLHC, "slhc_compress(): Header not yet seen, will memorize header for the next turn...\n"); comp->sls_o_misses++; comp->xmit_oldest = lcs->cs_this; goto uncompressed; found: + DEBUGP(DSLHC, "slhc_compress(): Header already seen, trying to compress...\n"); /* * Found it -- move to the front on the connection list. */ @@ -344,6 +372,39 @@ */ oth = &cs->cs_tcp; + /* Display a little more debug information about which of the + * header fields changed unexpectedly */ + if(ip->version != cs->cs_ip.version) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->version != cs->cs_ip.version\n"); + if(ip->ihl != cs->cs_ip.ihl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ihl != cs->cs_ip.ihl\n"); + if(ip->tos != cs->cs_ip.tos) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->tos != cs->cs_ip.tos\n"); + if((ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))\n"); + if(ip->ttl != cs->cs_ip.ttl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ttl != cs->cs_ip.ttl\n"); + if(th->doff != cs->cs_tcp.doff) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: th->doff != cs->cs_tcp.doff\n"); + if(ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): ip->ihl = %i\n", ip->ihl); + DEBUGP(DSLHC, "slhc_compress(): ip+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(ip+1),((ip->ihl)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: cs->cs_ipopt = %s\n", + osmo_hexdump_nospc((uint8_t*)(cs->cs_ipopt),((ip->ihl)-5)*4)); + } + if(th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): th->doff = %i\n", th->doff); + DEBUGP(DSLHC, "slhc_compress(): th+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(th+1),((th->doff)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): cs->cs_tcpopt = %s\n", + osmo_hexdump_nospc((uint8_t*)cs->cs_tcpopt, + ((th->doff)-5)*4)); + } + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl || ip->tos != cs->cs_ip.tos || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) @@ -351,6 +412,7 @@ || th->doff != cs->cs_tcp.doff || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + DEBUGP(DSLHC, "slhc_compress(): The header contains unexpected changes, can't compress...\n"); goto uncompressed; } @@ -362,6 +424,7 @@ */ if(th->urg){ deltaS = ntohs(th->urg_ptr); + DEBUGP(DSLHC, "slhc_compress(): flag: Urgent Pointer (U) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_U; } else if(th->urg_ptr != oth->urg_ptr){ @@ -369,21 +432,29 @@ * implementation should never do this but RFC793 * doesn't prohibit the change so we have to deal * with it. */ + DEBUGP(DSLHC, "slhc_compress(): URG not set but urp changed, can't compress...\n"); goto uncompressed; } if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Window (W) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_W; } if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ - if(deltaA > 0x0000ffff) + if(deltaA > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Ack (A) = 1\n"); cp = encode(cp,deltaA); changes |= NEW_A; } if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ - if(deltaS > 0x0000ffff) + if(deltaS > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_S; } @@ -399,17 +470,21 @@ if(ip->tot_len != cs->cs_ip.tot_len && ntohs(cs->cs_ip.tot_len) == hlen) break; + DEBUGP(DSLHC, "slhc_compress(): Retransmitted packet detected, can't compress...\n"); goto uncompressed; case SPECIAL_I: case SPECIAL_D: /* actual changes match one of our special case encodings -- * send packet uncompressed. */ + DEBUGP(DSLHC, "slhc_compress(): Special case detected, can't compress...\n"); goto uncompressed; case NEW_S|NEW_A: if(deltaS == deltaA && deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_compress(): Special case for echoed terminal traffic detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_I; cp = new_seq; } @@ -417,6 +492,8 @@ case NEW_S: if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for data xfer */ + DEBUGP(DSLHC, "slhc_compress(): Special case for data xfer detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Ack (A) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_D; cp = new_seq; } @@ -424,11 +501,14 @@ } deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); if(deltaS != 1){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta IP ID (I) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_I; } - if(th->psh) + if(th->psh) { + DEBUGP(DSLHC, "slhc_compress(): flag: Push (P) = 1\n"); changes |= TCP_PUSH_BIT; + } /* Grab the cksum before we overwrite it below. Then update our * state with this packet's header. */ @@ -445,6 +525,7 @@ if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ cp = ocp; *cpp = ocp; + DEBUGP(DSLHC, "slhc_compress(): flag: Connection number (C) = 1\n"); *cp++ = changes | NEW_C; *cp++ = cs->cs_this; comp->xmit_current = cs->cs_this; @@ -456,6 +537,10 @@ *(__sum16 *)cp = csum; cp += 2; /* deltaS is now the size of the change section of the compressed header */ + + DEBUGP(DSLHC, "slhc_compress(): Delta-list length (deltaS) = %li\n",deltaS); + DEBUGP(DSLHC, "slhc_compress(): Original header len (hlen) = %i\n",hlen); + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ memcpy(cp+deltaS,icp+hlen,isize-hlen); comp->sls_o_compressed++; @@ -467,6 +552,7 @@ * to use on future compressed packets in the protocol field). */ uncompressed: + DEBUGP(DSLHC, "slhc_compress(): Packet will be sent uncompressed...\n"); memcpy(&cs->cs_ip,ip,20); memcpy(&cs->cs_tcp,th,20); if (ip->ihl > 5) @@ -538,6 +624,8 @@ switch(changes & SPECIALS_MASK){ case SPECIAL_I: /* Echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_uncompress(): Echoed terminal traffic detected\n"); + { register short i; i = ntohs(ip->tot_len) - hdrlen; @@ -547,11 +635,13 @@ break; case SPECIAL_D: /* Unidirectional data */ + DEBUGP(DSLHC, "slhc_uncompress(): Unidirectional data detected\n"); thp->seq = htonl( ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen); break; default: + DEBUGP(DSLHC, "slhc_uncompress(): default packet type detected\n"); if(changes & NEW_U){ thp->urg = 1; if((x = decode(&cp)) == -1) { @@ -601,6 +691,7 @@ ip->tot_len = htons(len); ip->check = 0; + DEBUGP(DSLHC, "slhc_uncompress(): making space for the reconstructed header...\n"); memmove(icp + hdrlen, cp, len - hdrlen); cp = icp; @@ -625,6 +716,7 @@ return len; bad: + DEBUGP(DSLHC, "slhc_uncompress(): bad packet detected!\n"); comp->sls_i_error++; return slhc_toss( comp ); } @@ -641,6 +733,7 @@ if(isize < 20) { /* The packet is shorter than a legal IP header */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The packet is shorter than a legal IP header ==> slhc_toss()\n"); return slhc_toss( comp ); } /* Peek at the IP header's IHL field to find its length */ @@ -648,6 +741,7 @@ if(ihl < 20 / 4){ /* The IP header length field is too small */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The IP header length field is too small ==> slhc_toss()\n"); return slhc_toss( comp ); } index = icp[9]; @@ -656,10 +750,12 @@ if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; + DEBUGP(DSLHC, "slhc_remember(): Bad IP header checksum; discard ==> slhc_toss()\n"); return slhc_toss( comp ); } if(index > comp->rslot_limit) { comp->sls_i_error++; + DEBUGP(DSLHC, "slhc_remember(): index > comp->rslot_limit ==> slhc_toss()\n"); return slhc_toss(comp); } @@ -683,6 +779,7 @@ int slhc_toss(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_toss(): Reset compression state...\n"); if ( comp == NULLSLCOMPR ) return 0; @@ -690,55 +787,27 @@ return 0; } -#else /* CONFIG_INET */ - -int -slhc_toss(struct slcompress *comp) +void slhc_i_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); - return -EINVAL; -} -int -slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); - return -EINVAL; -} -int -slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_i_status(): %d Cmp, %d Uncmp, %d Bad, %d Tossed\n", + comp->sls_i_compressed, + comp->sls_i_uncompressed, + comp->sls_i_error, + comp->sls_i_tossed); + } } -int -slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +void slhc_o_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_o_status(): %d Cmp, %d Uncmp, %d AsIs, %d NotTCP %d Searches, %d Misses\n", + comp->sls_o_compressed, + comp->sls_o_uncompressed, + comp->sls_o_tcp, + comp->sls_o_nontcp, + comp->sls_o_searches, + comp->sls_o_misses); + } } -void -slhc_free(struct slcompress *comp) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); -} -struct slcompress * -slhc_init(int rslots, int tslots) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); - return NULL; -} - -#endif /* CONFIG_INET */ - -/* VJ header compression */ -EXPORT_SYMBOL(slhc_init); -EXPORT_SYMBOL(slhc_free); -EXPORT_SYMBOL(slhc_remember); -EXPORT_SYMBOL(slhc_compress); -EXPORT_SYMBOL(slhc_uncompress); -EXPORT_SYMBOL(slhc_toss); - -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 1debb2d..d5aa356 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid +SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid slhc if BUILD_NAT SUBDIRS += bsc-nat bsc-nat-trie diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 45d1780..3e66978 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -32,6 +32,7 @@ $(top_builddir)/src/gprs/oap_messages.o \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(top_builddir)/src/gprs/slhc.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ diff --git a/openbsc/tests/slhc/Makefile.am b/openbsc/tests/slhc/Makefile.am new file mode 100644 index 0000000..d21990f --- /dev/null +++ b/openbsc/tests/slhc/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = slhc_test.ok + +noinst_PROGRAMS = slhc_test + +slhc_test_SOURCES = slhc_test.c + +slhc_test_LDADD = \ + $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp -lrt -lm + + diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c new file mode 100644 index 0000000..59a5425 --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.c @@ -0,0 +1,298 @@ +/* Test SLHC/RFC1144 TCP/IP Header compression/decompression */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +/* Number of compression slots (S0-1) */ +#define SLOTS 8 + +/* Maximum packet bytes to display */ +#define DISP_MAX_BYTES 100 + +/* Sample packets to test with */ +#define PACKETS_LEN 6 +char *packets[] = { + "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", + "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", + "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", + "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" +}; + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int compress(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + uint8_t *comp_ptr; /* Not used */ + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int expand(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + int data_decompressed_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Handle an uncompressed packet (learn header information */ + if ((data_i[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Calculate IP Header checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Check TCP/IP packet */ +static void check_packet(const void *ctx, uint8_t *packet, int len) +{ + /* Check IP header */ + OSMO_ASSERT(len > 20); + OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + + /* Check TCP packet */ + if (packet[9] != 0x06) + return; + OSMO_ASSERT(len > 40); + OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); +} + +/* Strip TCP options from TCP/IP packet */ +static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) +{ + uint8_t doff; + uint16_t csum; + + /* Check if the packet can be handled here */ + if (len < 37) + return len; + if (packet[9] != 0x06) + return len; + + /* Strip TCP/IP options from packet */ + doff = ((packet[32] >> 4) & 0x0F) * 4; + memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); + len = len - (doff - 20); + + /* Repair data offset (TCP header length) */ + packet[32] &= 0x0F; + packet[32] |= 0x50; + + /* Repair checksum */ + packet[36] = 0; + packet[37] = 0; + csum = calc_tcpip_csum(ctx, packet, len); + packet[36] = csum & 0xFF; + packet[37] = csum >> 8 & 0xFF; + + /* Repair total length */ + packet[3] = len & 0xFF; + packet[2] = len >> 8 & 0xFF; + + /* Repair IP header checksum */ + packet[10] = 0; + packet[11] = 0; + csum = calc_ip_csum(packet, 20); + packet[10] = csum & 0xFF; + packet[11] = csum >> 8 & 0xFF; + printf("csum=%04x\n", csum); + + return len; +} + +/* Compress / Decompress packets */ +static void test_slhc(const void *ctx) +{ + char packet_ascii[2048]; + int i; + + struct slcompress *comp; + uint8_t packet[1024]; + int packet_len; + uint8_t packet_compr[1024]; + int packet_compr_len; + uint8_t packet_decompr[1024]; + int packet_decompr_len; + + printf("Allocating compression state...\n"); + comp = slhc_init(ctx, SLOTS, SLOTS); + OSMO_ASSERT(comp); + + for(i=0;i DISP_MAX_BYTES) + packet_compr_len = DISP_MAX_BYTES; + if (packet_len > DISP_MAX_BYTES) + packet_len = DISP_MAX_BYTES; + if (packet_decompr_len > DISP_MAX_BYTES) + packet_decompr_len = DISP_MAX_BYTES; + printf("Original Packet: (%i bytes) %s\n", packet_len, + osmo_hexdump_nospc(packet, packet_len)); + printf("DecompressedPacket: (%i bytes) %s\n", + packet_decompr_len, osmo_hexdump_nospc(packet_decompr, + packet_decompr_len)); + printf("CompressedPacket: (%i bytes) %s\n", packet_compr_len, + osmo_hexdump_nospc(packet_compr, packet_compr_len)); + slhc_o_status(comp); + slhc_o_status(comp); + + printf("\n"); + } + + printf("Freeing compression state...\n"); + slhc_free(comp); + printf("\n"); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + }, + [DSLHC] = { + .name = "DSLHC", + .description = + "Van Jacobson RFC1144 TCP/IP header compression (SLHC)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *ctx; + + osmo_init_logging(&info); + + ctx = talloc_named_const(NULL, 0, "slhc_ctx"); + + test_slhc(ctx); + + printf("Done\n"); + + talloc_report_full(ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/slhc/slhc_test.ok b/openbsc/tests/slhc/slhc_test.ok new file mode 100644 index 0000000..636241d --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.ok @@ -0,0 +1,52 @@ +Allocating compression state... +csum=b3a9 +Compressing... +Decompressing... +Results: +Original Packet: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +DecompressedPacket: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +CompressedPacket: (52 bytes) 7510003446dd40004000a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 + +csum=97a9 +Compressing... +Decompressing... +Results: +Original Packet: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +DecompressedPacket: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +CompressedPacket: (43 bytes) df00cda4fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 + +csum=baa9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +DecompressedPacket: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +CompressedPacket: (9 bytes) dc00a70a5227fffd01 + +csum=b9a9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +DecompressedPacket: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +CompressedPacket: (7 bytes) db00a706fffb01 + +csum=7ba9 +Compressing... +Decompressing... +Results: +Original Packet: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +DecompressedPacket: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +CompressedPacket: (68 bytes) db00c2d00d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a + +csum=aca9 +Compressing... +Decompressing... +Results: +Original Packet: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +DecompressedPacket: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +CompressedPacket: (18 bytes) df0021fb706f6c6c7578206c6f67696e3a20 + +Freeing compression state... + +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 85a81d6..5f37b8e 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -136,3 +136,8 @@ AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([slhc]) +AT_KEYWORDS([slhc]) +cat $abs_srcdir/slhc/slhc_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 17 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 11:55:22 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 2 Sep 2016 11:55:22 +0000 Subject: osmo-pcu[master]: Fix DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 1: > Holger, is your comment ("business logic") saying the same thing as > mine? i.e. that the patch duplicates a calculation that should be > in right. no code duplication! > So far I'm still expecting Arvind to un-duplicate. me too > a separate function called from both places. > > I'm afraid I don't follow on the latency/buffer bloat argument. Technical details about EGPRS window size: With EGPRS one can have a way bigger window (and select different sizes for UL and DL). While big windows are good for throughput it also means that _more_ data needs to be queued. The later is bad for latency and with "bufferbloat.org" the goal is to avoid queuing too much. Empirically Jacob came to the conclusion to not use the maximum possible window size but to have it proportionate to the amount of PDCHs (in use). -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 12:01:16 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 2 Sep 2016 12:01:16 +0000 Subject: osmo-pcu[master]: Fix DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 1: > > Holger, is your comment ("business logic") saying the same thing > > Empirically Jacob came to the conclusion to not use the maximum > possible window size but to have it proportionate to the amount of > PDCHs (in use). The technical details was meant for Neels. I have no objection to updating the window size where you update it but about the duplication of the calculation. Put it into a new method and call it from the two places. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 2 13:51:39 2016 From: gerrit-no-reply at lists.osmocom.org (daniel) Date: Fri, 2 Sep 2016 13:51:39 +0000 Subject: [PATCH] libosmocore[master]: gprs: Increase NS_ALLOC_SIZE to 3k Message-ID: Review at https://gerrit.osmocom.org/806 gprs: Increase NS_ALLOC_SIZE to 3k 2k can be insufficient when responding with a STATUS message to a long LLC packet because the original message is included in the STATUS. Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Ticket: SYS#2967 Sponsored-by: On-Waves ehf --- M include/osmocom/gprs/gprs_ns.h 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/06/806/1 diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h index 7c3b23c..130d8c0 100644 --- a/include/osmocom/gprs/gprs_ns.h +++ b/include/osmocom/gprs/gprs_ns.h @@ -23,7 +23,8 @@ "Alive Timer (Tns-alive) timeout\n" \ "Alive Timer (Tns-alive) number of retries\n" -#define NS_ALLOC_SIZE 2048 +/* Educated guess - LLC user payload is 1500 bytes plus possible headers */ +#define NS_ALLOC_SIZE 3072 #define NS_ALLOC_HEADROOM 20 enum ns_timeout { -- To view, visit https://gerrit.osmocom.org/806 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: daniel From gerrit-no-reply at lists.osmocom.org Fri Sep 2 16:17:08 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 16:17:08 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#28). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,443 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/28 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9a093ab..850eb42 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -19,7 +19,7 @@ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ - iu.h slhc.h + iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..fe3c4ec --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,48 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data_o, uint8_t *data_i, unsigned int len, + uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..2d70f5a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 245636b..2910c02 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,7 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 32920da..98084af 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -525,11 +547,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..c3020c9 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -143,6 +268,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +301,46 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + expnd = talloc_zero_size(msg, msg->len + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + sne->defrag.pcomp, sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } else + npdu_len = rc; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + talloc_free(expnd); + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +501,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +539,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +605,39 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; + uint8_t *compr; + uint8_t *msg_ptr; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_pcomp_compress(compr, msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); + talloc_free(compr); + return -EIO; + } else { + msgb_get(msg, msg->len); + msg_ptr = msgb_put(msg, rc); + memcpy(msg_ptr, compr, rc); + } + talloc_free(compr); +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +659,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +679,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +702,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +732,58 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + sne->defrag.pcomp, sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } else + npdu_len = rc; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + talloc_free(expnd); + return rc; } #if 0 @@ -619,3 +843,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..bf51a2e --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,289 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, + uint8_t *data_o, uint8_t *data_i, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + } else + *pcomp_index = 0; + + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, + uint8_t pcomp_index, struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data_o, data_i, len, pcomp_index, + comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data_o, data_i, + len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..6e6bbfd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -314,7 +317,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 3e66978..1804280 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -33,6 +33,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 28 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 2 16:17:08 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 2 Sep 2016 16:17:08 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/803 to look at the new patch set (#3). SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 636 insertions(+), 42 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/03/803/3 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9bea689..e21b485 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -20,7 +20,7 @@ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h v42bis.h \ - v42bis_private.h + v42bis_private.h gprs_sndcp_dcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..9a32e9e --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,55 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data_o, uint8_t *data_i, unsigned int len, + uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 2d70f5a..12d918e 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index f479d56..98abb3d 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,8 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c \ + gprs_sndcp_dcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index c3020c9..5344776 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -270,7 +271,8 @@ uint8_t *npdu; int npdu_len; int rc; - uint8_t *expnd; + uint8_t *hdr_expnd = NULL; + uint8_t *data_expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -314,18 +316,34 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - expnd = talloc_zero_size(msg, msg->len + MAX_HDRDECOMPR_INCR); - rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + /* Apply data decompression */ + data_expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC); + rc = gprs_sndcp_dcomp_expand(data_expnd, npdu, npdu_len, + sne->defrag.dcomp, sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data decompression failed!\n"); + talloc_free(data_expnd); + return -EIO; + } + + /* Apply header decompression */ + hdr_expnd = talloc_zero_size(msg, rc + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(hdr_expnd, data_expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return -EIO; - } else - npdu_len = rc; + } + + /* Modify npu length, hdr_expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + #if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + debug_ip_packet(hdr_expnd, npdu_len, 1, "defrag_segments()"); DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, " \n"); @@ -333,9 +351,10 @@ /* Hand off packet to gtp */ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); + sne->nsapi, msg, npdu_len, hdr_expnd); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return rc; } @@ -608,7 +627,8 @@ uint8_t pcomp = 0; uint8_t dcomp = 0; int rc; - uint8_t *compr; + uint8_t *hdr_compr = NULL; + uint8_t *data_compr = NULL; uint8_t *msg_ptr; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ @@ -620,19 +640,34 @@ DEBUGP(DSNDCP, "===================================================\n"); debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); #endif - compr = talloc_zero_size(msg, msg->len); - rc = gprs_sndcp_pcomp_compress(compr, msg->data, msg->len, &pcomp, + /* Apply header compression */ + hdr_compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_pcomp_compress(hdr_compr, msg->data, msg->len, &pcomp, lle->llme->comp.proto, nsapi); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); - talloc_free(compr); + talloc_free(hdr_compr); return -EIO; - } else { - msgb_get(msg, msg->len); - msg_ptr = msgb_put(msg, rc); - memcpy(msg_ptr, compr, rc); } - talloc_free(compr); + + /* Apply data compression */ + data_compr = talloc_zero_size(msg, msg->len); + rc = gprs_sndcp_dcomp_compress(data_compr, hdr_compr, rc, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); + talloc_free(hdr_compr); + talloc_free(data_compr); + return -EIO; + } + + /* Copy results back to msg buffer */ + msgb_get(msg, msg->len); + msg_ptr = msgb_put(msg, rc); + memcpy(msg_ptr, data_compr, rc); + + talloc_free(hdr_compr); + talloc_free(data_compr); #if DEBUG_IP_PACKETS == 1 DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); @@ -703,7 +738,8 @@ uint16_t npdu_num __attribute__((unused)); int npdu_len; int rc; - uint8_t *expnd; + uint8_t *hdr_expnd = NULL; + uint8_t *data_expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -761,18 +797,35 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); - rc = gprs_sndcp_pcomp_expand(expnd, npdu, npdu_len, + + /* Apply data decompression */ + data_expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC); + rc = gprs_sndcp_dcomp_expand(data_expnd, npdu, npdu_len, + sne->defrag.dcomp, sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data decompression failed!\n"); + talloc_free(data_expnd); + return -EIO; + } + + /* Apply header decompression */ + hdr_expnd = talloc_zero_size(msg, rc + MAX_HDRDECOMPR_INCR); + rc = gprs_sndcp_pcomp_expand(hdr_expnd, data_expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); + talloc_free(hdr_expnd); + talloc_free(data_expnd); return -EIO; - } else - npdu_len = rc; + } + + /* Modify npu length, hdr_expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + #if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + debug_ip_packet(hdr_expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); DEBUGP(DSNDCP, "===================================================\n"); DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, " \n"); @@ -780,9 +833,10 @@ /* Hand off packet to gtp */ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); + sne->nsapi, msg, npdu_len, hdr_expnd); - talloc_free(expnd); + talloc_free(data_expnd); + talloc_free(hdr_expnd); return rc; } @@ -851,8 +905,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -868,6 +925,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -975,13 +1049,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->v42bis_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..9b04a5f --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,366 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void v42bis_reset(v42bis_state_t *comp) +{ + /* This function performs a complete reset of the V.42bis compression + * state by reinitalizing the state withe the previously negotiated + * parameters. */ + + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data_o, + uint8_t *data_i, unsigned int len, + v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + uint8_t *data_c; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Run compressor */ + data_c = talloc_zero_size(NULL, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_c; + compressed_data.buf_pointer = data_c; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data_i, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + memcpy(data_o, data_i, len); + talloc_free(data_c); + return len; + } + + *pcomp_index = 1; + memcpy(data_o, data_c, compressed_data.len); + talloc_free(data_c); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int v42bis_expand_unitdata(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t pcomp_index, + v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + int rc; + struct v42bis_output_buffer uncompressed_data; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Decompress packet */ + uncompressed_data.buf = data_o; + uncompressed_data.buf_pointer = data_o; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + memcpy(data_o, data_i, len); + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = v42bis_expand_unitdata(data_o, data_i, len, pcomp_index, + comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data_o, uint8_t *data_i, + unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data_o); + OSMO_ASSERT(data_i); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + memcpy(data_o, data_i, len); + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = v42bis_compress_unitdata(&pcomp_index, data_o, data_i, + len, comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 894ce84..f01798b 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -297,6 +297,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 4d4431e..48b99b2 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -36,6 +36,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:07:53 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:07:53 +0000 Subject: [PATCH] osmo-bts[master]: LC15: fix coding style Message-ID: Review at https://gerrit.osmocom.org/807 LC15: fix coding style Change-Id: I18d07822df1f36a6855b72f83e2d73d221aa8735 --- M src/osmo-bts-litecell15/calib_file.c 1 file changed, 142 insertions(+), 143 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/07/807/1 diff --git a/src/osmo-bts-litecell15/calib_file.c b/src/osmo-bts-litecell15/calib_file.c index ac39e46..0714bc9 100644 --- a/src/osmo-bts-litecell15/calib_file.c +++ b/src/osmo-bts-litecell15/calib_file.c @@ -42,10 +42,9 @@ #include "lc15bts.h" #include "utils.h" -/** - * * Maximum calibration data chunk size - * */ +/* Maximum calibration data chunk size */ #define MAX_CALIB_TBL_SIZE 65536 +/* Calibration header version */ #define CALIB_HDR_V1 0x01 struct calib_file_desc { @@ -93,19 +92,19 @@ { struct { - uint8_t u8Version; // Header version (1) - uint8_t u8Parity; // Parity byte (xor) - uint8_t u8Type; // Table type (0:TX Downlink, 1:RX-A Uplink, 2:RX-B Uplink) - uint8_t u8Band; // GSM Band (0:GSM-850, 1:EGSM-900, 2:DCS-1800, 3:PCS-1900) - uint32_t u32Len; // Table length in bytes including the header + uint8_t u8Version; /* Header version (1) */ + uint8_t u8Parity; /* Parity byte (xor) */ + uint8_t u8Type; /* Table type (0:TX Downlink, 1:RX-A Uplink, 2:RX-B Uplink) */ + uint8_t u8Band; /* GSM Band (0:GSM-850, 1:EGSM-900, 2:DCS-1800, 3:PCS-1900) */ + uint32_t u32Len; /* Table length in bytes including the header */ struct { - uint32_t u32DescOfst; // Description section offset - uint32_t u32DateOfst; // Date section offset - uint32_t u32StationOfst; // Calibration test station section offset - uint32_t u32FpgaFwVerOfst; // Calibration FPGA firmware version section offset - uint32_t u32DspFwVerOfst; // Calibration DSP firmware section offset - uint32_t u32DataOfst; // Calibration data section offset + uint32_t u32DescOfst; /* Description section offset */ + uint32_t u32DateOfst; /* Date section offset */ + uint32_t u32StationOfst; /* Calibration test station section offset */ + uint32_t u32FpgaFwVerOfst; /* Calibration FPGA firmware version section offset */ + uint32_t u32DspFwVerOfst; /* Calibration DSP firmware section offset */ + uint32_t u32DataOfst; /* Calibration data section offset */ } toc; } v1; } hdr; @@ -137,7 +136,7 @@ { struct calib_send_state *st = &fl1h->st; char *calib_path = fl1h->phy_inst->u.lc15.calib_path; - char fname[PATH_MAX]; + char fname[PATH_MAX]; if (st->fp) { LOGP(DL1C, LOGL_NOTICE, "L1 calibration file was left opened !!\n"); @@ -145,9 +144,9 @@ st->fp = NULL; } - fname[0] = '\0'; - snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname); - fname[sizeof(fname)-1] = '\0'; + fname[0] = '\0'; + snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname); + fname[sizeof(fname)-1] = '\0'; st->fp = fopen(fname, "rb"); if (!st->fp) { @@ -225,14 +224,14 @@ rc = calib_file_open(fl1h, desc); if (rc < 0) { /* still, we'd like to continue trying to load - * calibration for all other bands */ - st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx); - if (st->last_file_idx >= 0) - return calib_file_send(fl1h, - &calib_files[st->last_file_idx]); + * calibration for all other bands */ + st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx); + if (st->last_file_idx >= 0) + return calib_file_send(fl1h, + &calib_files[st->last_file_idx]); LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n"); - return 0; + return 0; } rc = calib_verify(fl1h, desc); @@ -269,8 +268,8 @@ /* Skip this one and try the next one */ st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx); - if (st->last_file_idx >= 0) { - return calib_file_send(fl1h, + if (st->last_file_idx >= 0) { + return calib_file_send(fl1h, &calib_files[st->last_file_idx]); } @@ -307,152 +306,152 @@ static int calib_verify(struct lc15l1_hdl *fl1h, const struct calib_file_desc *desc) { - int rc, sz; - struct calib_send_state *st = &fl1h->st; - struct phy_link *plink = fl1h->phy_inst->phy_link; - char *rbuf; - struct calTbl_t *calTbl; - char calChkSum ; + int i, rc, sz; + struct calib_send_state *st = &fl1h->st; + struct phy_link *plink = fl1h->phy_inst->phy_link; + char *rbuf; + struct calTbl_t *calTbl; + char calChkSum ; - //calculate file size in bytes - fseek(st->fp, 0L, SEEK_END); - sz = ftell(st->fp); + /* calculate file size in bytes */ + fseek(st->fp, 0L, SEEK_END); + sz = ftell(st->fp); - //rewind read poiner - fseek(st->fp, 0L, SEEK_SET); + /* rewind read poiner */ + fseek(st->fp, 0L, SEEK_SET); - //read file - rbuf = (char *) malloc( sizeof(char) * sz ); + /* read file */ + rbuf = (char *) malloc( sizeof(char) * sz ); - rc = fread(rbuf, 1, sizeof(char) * sz, st->fp); - if ( rc != sz) { + rc = fread(rbuf, 1, sizeof(char) * sz, st->fp); + if (rc != sz) { + LOGP(DL1C, LOGL_ERROR, "%s reading error\n", desc->fname); + free(rbuf); - LOGP(DL1C, LOGL_ERROR, "%s reading error\n", desc->fname); - free(rbuf); + /* close file */ + rc = calib_file_close(fl1h); + if (rc < 0 ) { + LOGP(DL1C, LOGL_ERROR, "%s can not close\n", desc->fname); + return rc; + } - //close file - rc = calib_file_close(fl1h); - if (rc < 0 ) { - LOGP(DL1C, LOGL_ERROR, "%s can not close\n", desc->fname); - return rc; - } - - return -2; - } + return -2; + } - calTbl = (struct calTbl_t*) rbuf; - //calcualte file checksum - calChkSum = 0; - while ( sz-- ) { - calChkSum ^= rbuf[sz]; - } + calTbl = (struct calTbl_t*) rbuf; + /* calculate file checksum */ + calChkSum = 0; + while (sz--) { + calChkSum ^= rbuf[sz]; + } - //validate Tx calibration parity - if ( calChkSum ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid checksum %x.\n", desc->fname, calChkSum); - return -4; - } + /* validate Tx calibration parity */ + if (calChkSum) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid checksum %x.\n", desc->fname, calChkSum); + return -4; + } - //validate Tx calibration header - if ( calTbl->hdr.v1.u8Version != CALIB_HDR_V1 ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid header version %u.\n", desc->fname, calTbl->hdr.v1.u8Version); - return -5; - } + /* validate Tx calibration header */ + if (calTbl->hdr.v1.u8Version != CALIB_HDR_V1) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid header version %u.\n", desc->fname, calTbl->hdr.v1.u8Version); + return -5; + } - //validate calibration description - if ( calTbl->hdr.v1.toc.u32DescOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration description offset.\n", desc->fname); - return -6; - } + /* validate calibration description */ + if (calTbl->hdr.v1.toc.u32DescOfst == 0xFFFFFFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration description offset.\n", desc->fname); + return -6; + } - //validate calibration date - if ( calTbl->hdr.v1.toc.u32DateOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration date offset.\n", desc->fname); - return -7; - } + /* validate calibration date */ + if (calTbl->hdr.v1.toc.u32DateOfst == 0xFFFFFFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration date offset.\n", desc->fname); + return -7; + } - LOGP(DL1C, LOGL_INFO, "L1 calibration table %s created on %s\n", - desc->fname, - calTbl->u8RawData + calTbl->hdr.v1.toc.u32DateOfst); + LOGP(DL1C, LOGL_INFO, "L1 calibration table %s created on %s\n", + desc->fname, + calTbl->u8RawData + calTbl->hdr.v1.toc.u32DateOfst); - //validate calibration station - if ( calTbl->hdr.v1.toc.u32StationOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration station ID offset.\n", desc->fname); - return -8; - } + /* validate calibration station */ + if (calTbl->hdr.v1.toc.u32StationOfst == 0xFFFFFFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration station ID offset.\n", desc->fname); + return -8; + } - //validate FPGA FW version - if ( calTbl->hdr.v1.toc.u32FpgaFwVerOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid FPGA FW version offset.\n", desc->fname); - return -9; - } - //validate DSP FW version - if ( calTbl->hdr.v1.toc.u32DspFwVerOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid DSP FW version offset.\n", desc->fname); - return -10; - } + /* validate FPGA FW version */ + if (calTbl->hdr.v1.toc.u32FpgaFwVerOfst == 0xFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid FPGA FW version offset.\n", desc->fname); + return -9; + } - //validate Tx calibration data offset - if ( calTbl->hdr.v1.toc.u32DataOfst == 0xFFFFFFFF ) { - LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration data offset.\n", desc->fname); - return -11; - } + /* validate DSP FW version */ + if (calTbl->hdr.v1.toc.u32DspFwVerOfst == 0xFFFFFFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid DSP FW version offset.\n", desc->fname); + return -10; + } - if ( !desc->rx ) { + /* validate Tx calibration data offset */ + if (calTbl->hdr.v1.toc.u32DataOfst == 0xFFFFFFFF) { + LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration data offset.\n", desc->fname); + return -11; + } - //parse min/max Tx power - fl1h->phy_inst->u.lc15.minTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (5 << 2)]; - fl1h->phy_inst->u.lc15.maxTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (6 << 2)]; + if (!desc->rx) { - //override nominal Tx power of given TRX if needed - if ( fl1h->phy_inst->trx->nominal_power > fl1h->phy_inst->u.lc15.maxTxPower) { - LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n", - plink->num, - fl1h->phy_inst->u.lc15.maxTxPower, - fl1h->phy_inst->trx->nominal_power); + /* parse min/max Tx power */ + fl1h->phy_inst->u.lc15.minTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (5 << 2)]; + fl1h->phy_inst->u.lc15.maxTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (6 << 2)]; - fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.maxTxPower; - } + /* override nominal Tx power of given TRX if needed */ + if (fl1h->phy_inst->trx->nominal_power > fl1h->phy_inst->u.lc15.maxTxPower) { + LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n", + plink->num, + fl1h->phy_inst->u.lc15.maxTxPower, + fl1h->phy_inst->trx->nominal_power); - if ( fl1h->phy_inst->trx->nominal_power < fl1h->phy_inst->u.lc15.minTxPower) { - LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n", - plink->num, - fl1h->phy_inst->u.lc15.minTxPower, - fl1h->phy_inst->trx->nominal_power); + fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.maxTxPower; + } - fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.minTxPower; - } + if (fl1h->phy_inst->trx->nominal_power < fl1h->phy_inst->u.lc15.minTxPower) { + LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n", + plink->num, + fl1h->phy_inst->u.lc15.minTxPower, + fl1h->phy_inst->trx->nominal_power); - if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm > to_mdB(fl1h->phy_inst->u.lc15.maxTxPower) ) { - LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n", - plink->num, - to_mdB(fl1h->phy_inst->u.lc15.maxTxPower), - fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm); + fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.minTxPower; + } - fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.maxTxPower); - } + if (fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm > to_mdB(fl1h->phy_inst->u.lc15.maxTxPower) ) { + LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n", + plink->num, + to_mdB(fl1h->phy_inst->u.lc15.maxTxPower), + fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm); - if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm < to_mdB(fl1h->phy_inst->u.lc15.minTxPower) ) { - LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n", - plink->num, - to_mdB(fl1h->phy_inst->u.lc15.minTxPower), - fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm); + fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.maxTxPower); + } - fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.minTxPower); - } + if (fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm < to_mdB(fl1h->phy_inst->u.lc15.minTxPower) ) { + LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n", + plink->num, + to_mdB(fl1h->phy_inst->u.lc15.minTxPower), + fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm); - LOGP(DL1C, LOGL_DEBUG, "%s: minTxPower=%d, maxTxPower=%d\n", - desc->fname, - fl1h->phy_inst->u.lc15.minTxPower, - fl1h->phy_inst->u.lc15.maxTxPower ); - } + fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.minTxPower); + } - //rewind read poiner for subsequence tasks - fseek(st->fp, 0L, SEEK_SET); - free(rbuf); + LOGP(DL1C, LOGL_DEBUG, "%s: minTxPower=%d, maxTxPower=%d\n", + desc->fname, + fl1h->phy_inst->u.lc15.minTxPower, + fl1h->phy_inst->u.lc15.maxTxPower ); + } - return 0; + /* rewind read pointer for subsequence tasks */ + fseek(st->fp, 0L, SEEK_SET); + free(rbuf); + + return 0; } -- To view, visit https://gerrit.osmocom.org/807 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I18d07822df1f36a6855b72f83e2d73d221aa8735 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:07:54 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:07:54 +0000 Subject: [PATCH] osmo-bts[master]: LC15: Implementation of LC15 specific features Message-ID: Review at https://gerrit.osmocom.org/808 LC15: Implementation of LC15 specific features Change-Id: I79416faaa3ba328c9c2dabcd695a1b880fe666da --- M include/osmo-bts/gsm_data.h M include/osmo-bts/phy_link.h M src/common/Makefile.am M src/osmo-bts-litecell15/Makefile.am M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/lc15bts.c M src/osmo-bts-litecell15/lc15bts.h M src/osmo-bts-litecell15/lc15bts_vty.c M src/osmo-bts-litecell15/main.c 10 files changed, 346 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/08/808/1 diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index f1c9601..447d8d2 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -111,6 +111,12 @@ struct { char *sock_path; } pcu; +#ifdef ENABLE_LC15BTS + /* specific to LC15 BTS */ + struct { + uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */ + } lc15; +#endif }; enum lchan_ciph_state { diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index 82e73c8..f40d487 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -108,6 +108,12 @@ int minTxPower; int maxTxPower; struct lc15l1_hdl *hdl; + uint8_t max_cell_size; /* 0:166 qbits*/ + uint8_t diversity_mode; /* 0: SISO A, 1: SISO B, 2: MRC */ + uint8_t pedestal_mode; /* 0: unused TS is OFF, 1: unused TS is in minimum Tx power */ + uint8_t dsp_alive_period; /* DSP alive timer period */ + uint8_t tx_pwr_adj_mode; /* 0: no auto adjust power, 1: auto adjust power using RMS detector */ + uint8_t tx_pwr_red_8psk; /* 8-PSK maximum Tx power reduction level in dB */ } lc15; } u; }; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index fbb6572..e7ecebb 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -2,6 +2,10 @@ AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) +if ENABLE_LC15BTS +AM_CFLAGS += -DENABLE_LC15BTS +endif + noinst_LIBRARIES = libbts.a libl1sched.a libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ rsl.c vty.c paging.c measurement.c amr.c lchan.c \ diff --git a/src/osmo-bts-litecell15/Makefile.am b/src/osmo-bts-litecell15/Makefile.am index 3026e96..ea717ca 100644 --- a/src/osmo-bts-litecell15/Makefile.am +++ b/src/osmo-bts-litecell15/Makefile.am @@ -4,6 +4,8 @@ AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(ORTP_CFLAGS) COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) $(ORTP_LIBS) +AM_CFLAGS += -DENABLE_LC15BTS + EXTRA_DIST = misc/lc15bts_mgr.h misc/lc15bts_misc.h misc/lc15bts_par.h \ misc/lc15bts_temp.h misc/lc15bts_power.h misc/lc15bts_clock.h \ misc/lc15bts_bid.h misc/lc15bts_nl.h \ diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..e0000a2 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -1115,6 +1115,8 @@ GsmL1_Status_t status; int on = 0; unsigned int i; + struct gsm_bts *bts = trx->bts; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); if (sysp->id == Litecell15_PrimId_ActivateRfCnf) on = 1; @@ -1133,8 +1135,10 @@ LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n", get_value_string(lc15bts_l1status_names, status)); bts_shutdown(trx->bts, "RF-ACT failure"); - } else - bts_update_status(BTS_STATUS_RF_ACTIVE, 1); + } else { + if(btsb->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS) + bts_update_status(BTS_STATUS_RF_ACTIVE, 1); + } /* signal availability */ oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK); @@ -1145,7 +1149,8 @@ for (i = 0; i < ARRAY_SIZE(trx->ts); i++) oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); } else { - bts_update_status(BTS_STATUS_RF_ACTIVE, 0); + if(btsb->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS) + bts_update_status(BTS_STATUS_RF_ACTIVE, 0); oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); } @@ -1160,17 +1165,27 @@ { struct msgb *msg = sysp_msgb_alloc(); Litecell15_Prim_t *sysp = msgb_sysprim(msg); + struct phy_instance *pinst = hdl->phy_inst; if (on) { sysp->id = Litecell15_PrimId_ActivateRfReq; sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0; sysp->u.activateRfReq.msgq.u8UsePdtchMsgq = pcu_direct; - sysp->u.activateRfReq.u8UnusedTsMode = 0; + sysp->u.activateRfReq.u8UnusedTsMode = pinst->u.lc15.pedestal_mode; sysp->u.activateRfReq.u8McCorrMode = 0; + /* diversity mode: 0: SISO-A, 1: SISO-B, 2: MRC */ + sysp->u.activateRfReq.u8DiversityMode = pinst->u.lc15.diversity_mode; + /* maximum cell size in quarter-bits, 90 == 12.456 km */ - sysp->u.activateRfReq.u8MaxCellSize = 90; + sysp->u.activateRfReq.u8MaxCellSize = pinst->u.lc15.max_cell_size; + + /* auto tx power adjustment mode 0:none, 1: automatic*/ + sysp->u.activateRfReq.autoPowerAdjust.u8EnAutoPowerAdjust = pinst->u.lc15.tx_pwr_adj_mode; + + /* PSK modulation scheme maximum power level */ + sysp->u.activateRfReq.autoPowerAdjust.u8PowerReduction8Psk = pinst->u.lc15.tx_pwr_red_8psk; } else { sysp->id = Litecell15_PrimId_DeactivateRfReq; } @@ -1220,10 +1235,13 @@ oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0); } else { int i; + struct gsm_bts *bts = trx->bts; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", get_value_string(lc15bts_l1status_names, status)); - bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); + if(btsb->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS) + bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); osmo_static_assert( @@ -1449,6 +1467,53 @@ return 0; } +static void dsp_alive_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +{ + Litecell15_Prim_t *sysp = msgb_sysprim(resp); + Litecell15_IsAliveCnf_t *sac = &sysp->u.IsAliveCnf; + struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx); + + fl1h->hw_alive.dsp_alive_cnt++; + LOGP(DL1C, LOGL_NOTICE, "Rx SYS prim %s, status=%d (%d)\n", + get_value_string(lc15bts_sysprim_names, sysp->id), sac->status, trx->nr); + + msgb_free(resp); +} + +static int dsp_alive_timer_cb(void *data) +{ + struct lc15l1_hdl *fl1h = data; + struct gsm_bts_trx *trx = fl1h->phy_inst->trx; + struct msgb *msg = sysp_msgb_alloc(); + int rc; + + Litecell15_Prim_t *sys_prim = msgb_sysprim(msg); + sys_prim->id = Litecell15_PrimId_IsAliveReq; + + if (fl1h->hw_alive.dsp_alive_cnt == 0) { + + LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n", + get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr); + + exit(23); + } + + LOGP(DL1C, LOGL_NOTICE, "Tx SYS prim %s (%d)\n", + get_value_string(lc15bts_sysprim_names, sys_prim->id), trx->nr); + + rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL); + if (rc < 0) { + LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id)); + return -EIO; + } + + /* restart timer */ + fl1h->hw_alive.dsp_alive_cnt = 0; + osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0); + + return 0; +} + int bts_model_phy_link_open(struct phy_link *plink) { struct phy_instance *pinst = phy_instance_by_num(plink, 0); @@ -1468,6 +1533,24 @@ return -EIO; } + /* Set default PHY parameters */ + if (!pinst->u.lc15.max_cell_size) + pinst->u.lc15.max_cell_size = LC15_BTS_MAX_CELL_SIZE_DEFAULT; + + if (!pinst->u.lc15.diversity_mode) + pinst->u.lc15.diversity_mode = LC15_BTS_DIVERSITY_MODE_DEFAULT; + + if (!pinst->u.lc15.pedestal_mode) + pinst->u.lc15.pedestal_mode = LC15_BTS_PEDESTAL_MODE_DEFAULT; + + if (!pinst->u.lc15.dsp_alive_period) + pinst->u.lc15.dsp_alive_period = LC15_BTS_DSP_ALIVE_TMR_DEFAULT; + + if (!pinst->u.lc15.tx_pwr_adj_mode) + pinst->u.lc15.tx_pwr_adj_mode = LC15_BTS_TX_PWR_ADJ_DEFAULT; + + if (!pinst->u.lc15.tx_pwr_red_8psk) + pinst->u.lc15.tx_pwr_red_8psk = LC15_BTS_TX_RED_PWR_8PSK_DEFAULT; struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl; fl1h->dsp_trace_f = dsp_trace; @@ -1476,6 +1559,25 @@ phy_link_state_set(plink, PHY_LINK_CONNECTED); + /* Send first IS_ALIVE primitive */ + struct msgb *msg = sysp_msgb_alloc(); + int rc; + + Litecell15_Prim_t *sys_prim = msgb_sysprim(msg); + sys_prim->id = Litecell15_PrimId_IsAliveReq; + + rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL); + if (rc < 0) { + LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id)); + return -EIO; + } + + /* initialize DSP heart beat alive timer */ + fl1h->hw_alive.dsp_alive_timer.cb = dsp_alive_timer_cb; + fl1h->hw_alive.dsp_alive_timer.data = fl1h; + fl1h->hw_alive.dsp_alive_cnt = 0; + fl1h->hw_alive.dsp_alive_period = pinst->u.lc15.dsp_alive_period; + osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..8a7b737 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -59,6 +59,12 @@ struct calib_send_state st; uint8_t last_rf_mute[8]; + + struct { + struct osmo_timer_list dsp_alive_timer; + unsigned int dsp_alive_cnt; + uint8_t dsp_alive_period; + } hw_alive; }; #define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) diff --git a/src/osmo-bts-litecell15/lc15bts.c b/src/osmo-bts-litecell15/lc15bts.c index 172a7e4..778b9ef 100644 --- a/src/osmo-bts-litecell15/lc15bts.c +++ b/src/osmo-bts-litecell15/lc15bts.c @@ -121,6 +121,8 @@ case Litecell15_PrimId_MuteRfCnf: return L1P_T_CONF; case Litecell15_PrimId_SetRxAttenReq: return L1P_T_REQ; case Litecell15_PrimId_SetRxAttenCnf: return L1P_T_CONF; + case Litecell15_PrimId_IsAliveReq: return L1P_T_REQ; + case Litecell15_PrimId_IsAliveCnf: return L1P_T_CONF; default: return L1P_T_INVALID; } } @@ -142,6 +144,8 @@ { Litecell15_PrimId_MuteRfCnf, "MUTE-RF.cnf" }, { Litecell15_PrimId_SetRxAttenReq, "SET-RX-ATTEN.req" }, { Litecell15_PrimId_SetRxAttenCnf, "SET-RX-ATTEN-CNF.cnf" }, + { Litecell15_PrimId_IsAliveReq, "IS-ALIVE.req" }, + { Litecell15_PrimId_IsAliveCnf, "IS-ALIVE-CNF.cnf" }, { 0, NULL } }; @@ -155,6 +159,7 @@ case Litecell15_PrimId_SetCalibTblReq: return Litecell15_PrimId_SetCalibTblCnf; case Litecell15_PrimId_MuteRfReq: return Litecell15_PrimId_MuteRfCnf; case Litecell15_PrimId_SetRxAttenReq: return Litecell15_PrimId_SetRxAttenCnf; + case Litecell15_PrimId_IsAliveReq: return Litecell15_PrimId_IsAliveCnf; default: return -1; // Weak } } diff --git a/src/osmo-bts-litecell15/lc15bts.h b/src/osmo-bts-litecell15/lc15bts.h index 4c40db0..39a8168 100644 --- a/src/osmo-bts-litecell15/lc15bts.h +++ b/src/osmo-bts-litecell15/lc15bts.h @@ -22,6 +22,27 @@ L1P_T_IND, }; +enum lc15_diversity_mode{ + LC15_DIVERSITY_SISO_A = 0, + LC15_DIVERSITY_SISO_B, + LC15_DIVERSITY_MRC, +}; + +enum lc15_pedestal_mode{ + LC15_PEDESTAL_OFF = 0, + LC15_PEDESTAL_ON, +}; + +enum lc15_led_control_mode{ + LC15_LED_CONTROL_BTS = 0, + LC15_LED_CONTROL_EXT, +}; + +enum lc15_auto_pwr_adjust_mode{ + LC15_TX_PWR_ADJ_NONE = 0, + LC15_TX_PWR_ADJ_AUTO, +}; + enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id); const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1]; GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id); @@ -61,4 +82,13 @@ const uint8_t pdch_msu_size[_NUM_PDCH_CS]; +/* LC15 default parameters */ +#define LC15_BTS_MAX_CELL_SIZE_DEFAULT 166 /* 166 qbits is default value */ +#define LC15_BTS_DIVERSITY_MODE_DEFAULT 0 /* SISO-A is default mode */ +#define LC15_BTS_PEDESTAL_MODE_DEFAULT 0 /* Unused TS is off by default */ +#define LC15_BTS_LED_CTRL_MODE_DEFAULT 0 /* LED is controlled by BTS by default */ +#define LC15_BTS_DSP_ALIVE_TMR_DEFAULT 5 /* Default DSP alive timer is 5 seconds */ +#define LC15_BTS_TX_PWR_ADJ_DEFAULT 0 /* Default Tx power auto adjustment is none */ +#define LC15_BTS_TX_RED_PWR_8PSK_DEFAULT 0 /* Default 8-PSK maximum power level is 0 dB */ + #endif /* LC15BTS_H */ diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c index c5d404c..7b0f79b 100644 --- a/src/osmo-bts-litecell15/lc15bts_vty.c +++ b/src/osmo-bts-litecell15/lc15bts_vty.c @@ -65,6 +65,31 @@ static struct gsm_bts *vty_bts; +static const struct value_string lc15_diversity_mode_strs[] = { + { LC15_DIVERSITY_SISO_A, "siso-a" }, + { LC15_DIVERSITY_SISO_B, "siso-b" }, + { LC15_DIVERSITY_MRC, "mrc" }, + { 0, NULL } +}; + +static const struct value_string lc15_pedestal_mode_strs[] = { + { LC15_PEDESTAL_OFF, "off" }, + { LC15_PEDESTAL_ON, "on" }, + { 0, NULL } +}; + +static const struct value_string lc15_led_mode_strs[] = { + { LC15_LED_CONTROL_BTS, "bts" }, + { LC15_LED_CONTROL_EXT, "external" }, + { 0, NULL } +}; + +static const struct value_string lc15_auto_adj_pwr_strs[] = { + { LC15_TX_PWR_ADJ_NONE, "none" }, + { LC15_TX_PWR_ADJ_AUTO, "auto" }, + { 0, NULL } +}; + /* configuration */ DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd, @@ -321,8 +346,132 @@ return CMD_SUCCESS; } +DEFUN(cfg_phy_max_cell_size, cfg_phy_max_cell_size_cmd, + "max-cell-size <0-166>", + "Set the maximum cell size in qbits\n") +{ + struct phy_instance *pinst = vty->index; + int cell_size = (uint8_t)atoi(argv[0]); + + if (( cell_size > 166 ) || ( cell_size < 0 )) { + vty_out(vty, "Max cell size must be between 0 and 166 qbits (%d) %s", + cell_size, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.max_cell_size = (uint8_t)cell_size; + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_diversity_mode, cfg_phy_diversity_mode_cmd, + "diversity-mode (siso-a|siso-b|mrc)", + "Set reception diversity mode \n" + "Reception diversity mode can be (siso-a, siso-b, mrc)\n") +{ + struct phy_instance *pinst = vty->index; + int val = get_string_value(lc15_diversity_mode_strs, argv[0]); + + if((val < LC15_DIVERSITY_SISO_A) || (val > LC15_DIVERSITY_MRC)) { + vty_out(vty, "Invalid reception diversity mode %d%s", val, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.diversity_mode = (uint8_t)val; + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_pedestal_mode, cfg_phy_pedestal_mode_cmd, + "pedestal-mode (on|off)", + "Set unused time-slot transmission in pedestal mode\n" + "Transmission pedestal mode can be (off, on)\n") +{ + struct phy_instance *pinst = vty->index; + int val = get_string_value(lc15_pedestal_mode_strs, argv[0]); + + if((val < LC15_PEDESTAL_OFF) || (val > LC15_PEDESTAL_ON)) { + vty_out(vty, "Invalid unused time-slot transmission mode %d%s", val, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.pedestal_mode = (uint8_t)val; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_led_mode, cfg_bts_led_mode_cmd, + "led-control-mode (bts|external)", + "Set LED controlled by BTS or external software\n" + "LED can be controlled by (bts, external)\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + int val = get_string_value(lc15_led_mode_strs, argv[0]); + + if((val < LC15_LED_CONTROL_BTS) || (val > LC15_LED_CONTROL_EXT)) { + vty_out(vty, "Invalid LED control mode %d%s", val, VTY_NEWLINE); + return CMD_WARNING; + } + + btsb->lc15.led_ctrl_mode = (uint8_t)val; + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_dsp_alive_timer, cfg_phy_dsp_alive_timer_cmd, + "dsp-alive-period <0-60>", + "Set DSP alive timer period in second\n") +{ + struct phy_instance *pinst = vty->index; + uint8_t period = (uint8_t)atoi(argv[0]); + + if (( period > 60 ) || ( period < 0 )) { + vty_out(vty, "DSP heart beat alive timer period must be between 0 and 60 seconds (%d) %s", + period, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.dsp_alive_period = period; + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_auto_tx_pwr_adj, cfg_phy_auto_tx_pwr_adj_cmd, + "pwr-adj-mode (none|auto)", + "Set output power adjustment mode\n") +{ + struct phy_instance *pinst = vty->index; + int val = get_string_value(lc15_auto_adj_pwr_strs, argv[0]); + + if((val < LC15_TX_PWR_ADJ_NONE) || (val > LC15_TX_PWR_ADJ_AUTO)) { + vty_out(vty, "Invalid output power adjustment mode %d%s", val, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.tx_pwr_adj_mode = (uint8_t)val; + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_tx_red_pwr_8psk, cfg_phy_tx_red_pwr_8psk_cmd, + "tx-red-pwr-8psk <0-40>", + "Set reduction output power for 8-PSK scheme in dB unit\n") +{ + struct phy_instance *pinst = vty->index; + int val = atoi(argv[0]); + + if ((val > 40) || (val < 0)) { + vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s", + val, VTY_NEWLINE); + return CMD_WARNING; + } + + pinst->u.lc15.tx_pwr_red_8psk = (uint8_t)val; + return CMD_SUCCESS; +} + void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts) { + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + vty_out(vty, " led-control-mode %s%s", + get_value_string(lc15_led_mode_strs, btsb->lc15.led_ctrl_mode), VTY_NEWLINE); + } void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) @@ -343,8 +492,27 @@ } } if (pinst->u.lc15.calib_path) - vty_out(vty, " trx-calibration-path %s%s", + vty_out(vty, " trx-calibration-path %s%s", pinst->u.lc15.calib_path, VTY_NEWLINE); + + vty_out(vty, " max-cell-size %d%s", + pinst->u.lc15.max_cell_size, VTY_NEWLINE); + + vty_out(vty, " diversity-mode %s%s", + get_value_string(lc15_diversity_mode_strs, pinst->u.lc15.diversity_mode), VTY_NEWLINE); + + vty_out(vty, " pedestal-mode %s%s", + get_value_string(lc15_pedestal_mode_strs, pinst->u.lc15.pedestal_mode) , VTY_NEWLINE); + + vty_out(vty, " dsp-alive-period %d%s", + pinst->u.lc15.dsp_alive_period, VTY_NEWLINE); + + vty_out(vty, " pwr-adj-mode %s%s", + get_value_string(lc15_auto_adj_pwr_strs, pinst->u.lc15.tx_pwr_adj_mode), VTY_NEWLINE); + + vty_out(vty, " tx-red-pwr-8psk %d%s", + pinst->u.lc15.tx_pwr_red_8psk, VTY_NEWLINE); + } void bts_model_config_write_phy(struct vty *vty, struct phy_link *plink) @@ -405,12 +573,20 @@ install_element(BTS_NODE, &cfg_bts_auto_band_cmd); install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd); + install_element(BTS_NODE, &cfg_bts_led_mode_cmd); install_element(TRX_NODE, &cfg_trx_nominal_power_cmd); install_element(PHY_INST_NODE, &cfg_phy_dsp_trace_f_cmd); install_element(PHY_INST_NODE, &cfg_phy_no_dsp_trace_f_cmd); install_element(PHY_INST_NODE, &cfg_phy_cal_path_cmd); + install_element(PHY_INST_NODE, &cfg_phy_diversity_mode_cmd); + install_element(PHY_INST_NODE, &cfg_phy_pedestal_mode_cmd); + install_element(PHY_INST_NODE, &cfg_phy_max_cell_size_cmd); + install_element(PHY_INST_NODE, &cfg_phy_dsp_alive_timer_cmd); + install_element(PHY_INST_NODE, &cfg_phy_auto_tx_pwr_adj_cmd); + install_element(PHY_INST_NODE, &cfg_phy_tx_red_pwr_8psk_cmd); + return 0; } diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c index 352949b..a74da8a 100644 --- a/src/osmo-bts-litecell15/main.c +++ b/src/osmo-bts-litecell15/main.c @@ -72,6 +72,8 @@ btsb = bts_role_bts(bts); btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + /* specific default values for LC15 platform */ + btsb->lc15.led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT; rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/808 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I79416faaa3ba328c9c2dabcd695a1b880fe666da Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:07:54 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:07:54 +0000 Subject: [PATCH] osmo-bts[master]: LC15: Implementation of major BTS alarms Message-ID: Review at https://gerrit.osmocom.org/809 LC15: Implementation of major BTS alarms Change-Id: Ic4e088a3af115d3d5a124b61c1e92eed277d3469 --- M include/osmo-bts/gsm_data.h M include/osmo-bts/oml.h M src/common/bts.c M src/common/l1sap.c M src/common/main.c M src/common/oml.c M src/common/pcu_sock.c M src/common/rsl.c M src/osmo-bts-litecell15/calib_file.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h 11 files changed, 553 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/09/809/1 diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 447d8d2..ed864d6 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -115,6 +115,7 @@ /* specific to LC15 BTS */ struct { uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */ + struct llist_head ceased_alarm_list; /* ceased alarm list*/ } lc15; #endif }; diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 9f49444..b3ccf9d 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -1,11 +1,76 @@ #ifndef _OML_H #define _OML_H +#include "openbsc/signal.h" struct gsm_bts; struct gsm_abis_mo; struct msgb; struct gsm_lchan; +enum oml_fail_evt_rep_sig { + S_NM_OML_PCU_CONN_LOST_ALARM = 0x0a1a, + S_NM_OML_PCU_CONN_LOST_CEASED, + S_NM_OML_PCU_CONN_NOT_AVAIL_ALARM, + S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM, + S_NM_OML_BTS_RSL_FAILED_ALARM, + S_NM_OML_BTS_RF_DEACT_FAILED_ALARM, + S_NM_OML_BTS_RX_SIGINT_MSG_ALARM, + S_NM_OML_BTS_RX_SIGX_MSG_ALARM, + S_NM_OML_BTS_DSP_ALIVE_ALARM, + S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM, + S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM, + S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM, + S_NM_OML_BTS_PAG_TBL_FULL_ALARM, + S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM, + S_NM_OML_BTS_FAIL_RTP_BIND_ALARM, + S_NM_OML_BTS_NO_RTP_SOCK_ALARM, + S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM, + S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, + S_NM_OML_BTS_NO_CALIB_PATH_ALARM, +}; + +struct oml_fail_evt_rep_sig_data { + struct gsm_abis_mo *mo; + uint8_t event_type; + uint8_t event_serverity; + uint8_t cause_type; + uint16_t event_cause; + char *add_text; + int rc; + uint8_t spare[4]; +}; + +struct oml_alarm_list { + struct llist_head list; /* List of sent failure alarm report */ + uint16_t alarm_signal; /* Failure alarm report signal cause */ +}; + +enum abis_nm_failure_event_causes { + /* Critical causes */ + NM_EVT_CAUSE_CRIT_SW_FATAL = 0x3000, + NM_EVT_CAUSE_CRIT_DSP_FATAL = 0x3001, + NM_EVT_CAUSE_CRIT_PROC_STOP = 0x3006, + NM_EVT_CAUSE_CRIT_RTP_CREATE_FAIL = 0x332a, + NM_EVT_CAUSE_CRIT_RTP_BIND_FAIL = 0x332b, + NM_EVT_CAUSE_CRIT_RTP_NO_SOCK = 0x332c, + NM_EVT_CAUSE_CRIT_BAD_CALIB_PATH = 0x3401, + NM_EVT_CAUSE_CRIT_OPEN_CALIB_FAIL = 0x3403, + NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL = 0x3404, + /* Major causes */ + NM_EVT_CAUSE_MAJ_UKWN_PCU_MSG = 0x3002, + NM_EVT_CAUSE_MAJ_UKWN_DL_MSG = 0x3003, + NM_EVT_CAUSE_MAJ_UKWN_UL_MSG = 0x3004, + NM_EVT_CAUSE_MAJ_UKWN_MPH_MSG = 0x3005, + NM_EVT_CAUSE_MAJ_RSL_FAIL = 0x3309, + NM_EVT_CAUSE_MAJ_DEACT_RF_FAIL = 0x330a, + /* Minor causes */ + NM_EVT_CAUSE_MIN_PAG_TAB_FULL = 0x3402, + /* Warning causes */ + NM_EVT_CAUSE_WARN_SW_WARN = 0x0001, + +}; + +extern struct oml_fail_evt_rep_sig_data alarm_sig_data; int oml_init(void); int down_oml(struct gsm_bts *bts, struct msgb *msg); @@ -42,4 +107,10 @@ int oml_set_lchan_t200(struct gsm_lchan *lchan); extern const unsigned int oml_default_t200_ms[7]; +/* Transmit failure event report */ +int oml_tx_nm_fail_evt_rep(struct gsm_abis_mo *mo, uint8_t event_type, uint8_t event_serverity, uint8_t cause_type, uint16_t event_cause, char *add_text); + +/* Initialize failure report signalling */ +int oml_failure_report_init(void *handler); + #endif // _OML_H */ diff --git a/src/common/bts.c b/src/common/bts.c index 6f621c4..42ac096 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -44,6 +44,7 @@ #include #include #include +#include "osmo-bts/oml.h" #define MIN_QUAL_RACH 5.0f /* at least 5 dB C/I */ #define MIN_QUAL_NORM -0.5f /* at least -1 dB C/I */ @@ -175,6 +176,9 @@ INIT_LLIST_HEAD(&btsb->smscb_state.queue); INIT_LLIST_HEAD(&btsb->oml_queue); +#ifdef ENABLE_LC15BTS + INIT_LLIST_HEAD(&btsb->lc15.ceased_alarm_list); +#endif return rc; } @@ -250,6 +254,7 @@ int trx_link_estab(struct gsm_bts_trx *trx) { struct e1inp_sign_link *link = trx->rsl_link; + int rc; uint8_t radio_state = link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED; LOGP(DSUM, LOGL_INFO, "RSL link (TRX %02x) state changed to %s, sending Status'.\n", @@ -258,11 +263,19 @@ oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK); if (link) - rsl_tx_rf_res(trx); + rc = rsl_tx_rf_res(trx); else - bts_model_trx_deact_rf(trx); + rc = bts_model_trx_deact_rf(trx); - return 0; + if(rc < 0) { + alarm_sig_data.mo = &trx->mo; + if(link) + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RSL_FAILED_ALARM, &alarm_sig_data); + else + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RF_DEACT_FAILED_ALARM, &alarm_sig_data); + } + + return rc; } /* set the availability of the TRX (used by PHY driver) */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7c30c9b..b3253a8 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -46,6 +46,7 @@ #include #include #include +#include "osmo-bts/oml.h" struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx, unsigned int chan_nr) @@ -1003,7 +1004,11 @@ break; default: LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n", - l1sap->oph.primitive, l1sap->oph.operation); + l1sap->oph.primitive, l1sap->oph.operation); + + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->oph.primitive, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM, &alarm_sig_data); break; } diff --git a/src/common/main.c b/src/common/main.c index 5e0f1a1..62d7150 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -50,6 +50,7 @@ #include #include #include +#include int quit = 0; static const char *config_file = "osmo-bts.cfg"; @@ -181,13 +182,21 @@ switch (signal) { case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); - if (!quit) + if (!quit) { + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_SIGINT_MSG_ALARM, &alarm_sig_data); + bts_shutdown(bts, "SIGINT"); + } quit++; break; case SIGABRT: case SIGUSR1: case SIGUSR2: + alarm_sig_data.mo = &bts->mo; + alarm_sig_data.spare[0] = signal; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_SIGX_MSG_ALARM, &alarm_sig_data); + talloc_report_full(tall_bts_ctx, stderr); break; default: @@ -248,6 +257,8 @@ e1inp_vty_init(); bts_vty_init(bts, &bts_log_info); + oml_failure_report_init(NULL); + /* enable realtime priority for us */ if (rt_prio != -1) { struct sched_param param; diff --git a/src/common/oml.c b/src/common/oml.c index 690a81d..924c4dc 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -41,6 +41,12 @@ #include #include #include +#include +#include +#ifdef ENABLE_LC15BTS +#include "../osmo-bts-litecell15/lc15bts.h" +struct oml_fail_evt_rep_sig_data alarm_sig_data; +#endif /* FIXME: move this to libosmocore */ static struct tlv_definition abis_nm_att_tlvdef_ipa = { @@ -367,6 +373,37 @@ msgb_put(nmsg, sizeof(struct abis_om_fom_hdr)); return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP); +} + +/* TS 12.21 8.8.2 */ +int oml_tx_nm_fail_evt_rep(struct gsm_abis_mo *mo, uint8_t event_type, uint8_t event_serverity, uint8_t cause_type, uint16_t event_cause, char *add_text) +{ + struct msgb *nmsg; + uint8_t cause[3]; + int i, len; + + LOGP(DOML, LOGL_INFO, "%s Tx FAILure EVT REP\n", gsm_abis_mo_name(mo)); + + nmsg = oml_msgb_alloc(); + if (!nmsg) + return -ENOMEM; + + msgb_tv_put(nmsg, NM_ATT_EVENT_TYPE, event_type); + msgb_tv_put(nmsg, NM_ATT_SEVERITY, event_serverity); + + cause[0] = cause_type; + for (i = 0; i < 2 ; i++) + cause[i + 1] = ((uint8_t*)&event_cause)[1 - i]; + + msgb_tv_fixed_put(nmsg, NM_ATT_PROB_CAUSE, 3, cause); + + len = strlen(add_text); + if(len){ + LOGP(DOML, LOGL_DEBUG, "%s Tx FAILure EVT REP Additional Text = %s (%d)\n", gsm_abis_mo_name(mo), add_text, len); + msgb_tl16v_put(nmsg, NM_ATT_ADD_TEXT, len, add_text); + } + + return oml_mo_send_msg(mo, nmsg, NM_MT_FAILURE_EVENT_REP); } /* TS 12.21 9.4.53 */ @@ -1268,3 +1305,265 @@ return 0; } + +static int handle_oml_fail_evt_rep_sig(unsigned int subsys, unsigned int signal, + void *handler_data, void *_signal_data) +{ + struct oml_fail_evt_rep_sig_data *sig_data = _signal_data; + int rc = 0; + unsigned int res; + char log_msg[100]; + + if (subsys != SS_NM) + return 0; + + switch (signal) { + case S_NM_OML_PCU_CONN_LOST_ALARM: + snprintf(log_msg, 100, "PCU socket has LOST connection\n"); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_SW_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_PCU_CONN_LOST_CEASED: + snprintf(log_msg, 100, "PCU socket has LOST connection\n"); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CEASED, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_SW_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM: + snprintf(log_msg, 100, "Received unknown PCU msg type 0x%02x\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_PCU_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RSL_FAILED_ALARM: + snprintf(log_msg, 100, "Failed to establish RSL link (%d)\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_RSL_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RF_DEACT_FAILED_ALARM: + snprintf(log_msg, 100, "Failed to deactivate RF (%d)\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_DEACT_RF_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown prim %d L1SAP UP trx %d\n", sig_data->mo->obj_inst.trx_nr, res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_UL_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown prim %d L1SAP DOWN trx %d\n", sig_data->mo->obj_inst.trx_nr, res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_DL_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_SIGINT_MSG_ALARM: + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_PROC_STOP, + "BTS: signal SIGINT received -> shutdown\n"); + break; + + case S_NM_OML_BTS_RX_SIGX_MSG_ALARM: + snprintf(log_msg, 100, "BTS: signal %d received\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_PROC_STOP, + sig_data->add_text); + break; + + case S_NM_OML_BTS_DSP_ALIVE_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "Timeout waiting for SYS primitive %s (%d)\n", + get_value_string(lc15bts_sysprim_names, res + 1), sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_DSP_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown MPH-INFO.req %d\n", res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_MPH_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_PAG_TBL_FULL_ALARM: + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_ENV_FAIL, + NM_SEVER_MINOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MIN_PAG_TAB_FULL, + "BTS page table is full\n"); + break; + + case S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM: + snprintf(log_msg, 100, "IPAC Failed to create RTP/RTCP sockets, trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_CREATE_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_FAIL_RTP_BIND_ALARM: + snprintf(log_msg, 100, "IPAC Failed to bind RTP/RTCP sockets, trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_BIND_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_NO_RTP_SOCK_ALARM: + snprintf(log_msg, 100, "Rx RSL IPAC MDCX, but we have no RTP socket! trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_NO_SOCK, + sig_data->add_text); + break; + + case S_NM_OML_BTS_NO_CALIB_PATH_ALARM: + snprintf(log_msg, 100, "Calibration file path for trx=%d not specified\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_BAD_CALIB_PATH, + sig_data->add_text); + break; + + + case S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM: + memcpy(&res, sig_data->spare, sizeof(int)); + snprintf(log_msg, 100, "Failed to open L1 calibration table %s -> failed (%d)\n", + sig_data->add_text, + res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_OPEN_CALIB_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM: + memcpy(&res, sig_data->spare, sizeof(int)); + snprintf(log_msg, 100, "Verify L1 calibration table %s -> failed (%d)\n", + sig_data->add_text, + res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL, + sig_data->add_text); + break; + + default: + break; + } + + sig_data->rc = rc; + return 0; +} + +int oml_failure_report_init(void *handler) +{ + /* register for failure report events */ + osmo_signal_register_handler(SS_NM, handle_oml_fail_evt_rep_sig, handler); + + return 0; +} diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 62f18a7..bd50be1 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -41,6 +41,7 @@ #include #include #include +#include uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); @@ -131,12 +132,14 @@ struct gsm_bts_gprs_nsvc *nsvc; struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; - int i, j; + int i, j, rc; + struct gsm_bts_role_bts *btsb; LOGP(DPCU, LOGL_INFO, "Sending info\n"); /* FIXME: allow multiple BTS */ bts = llist_entry(net->bts_list.next, struct gsm_bts, list); + btsb = bts_role_bts(bts); rlcc = &bts->gprs.cell.rlc_cfg; msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr); @@ -245,7 +248,25 @@ } } - return pcu_sock_send(net, msg); + rc = pcu_sock_send(net, msg); + if (rc < 0) + return rc; + +#ifdef ENABLE_LC15BTS + struct oml_alarm_list *ceased_alarm; + /* check for pending ceased alarm */ + llist_for_each_entry(ceased_alarm, &btsb->lc15.ceased_alarm_list, list) { + llist_del(&ceased_alarm->list); + if (ceased_alarm->alarm_signal != S_NM_OML_PCU_CONN_LOST_ALARM) + continue; + + LOGP(DPCU, LOGL_ERROR, "Alarm %d has removed from pending ceased alarm list\n", ceased_alarm->alarm_signal); + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_LOST_CEASED, &alarm_sig_data); + break; + } +#endif + return 0; } static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal, @@ -603,6 +624,9 @@ default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); + alarm_sig_data.mo = &bts->mo; + alarm_sig_data.spare[0] = msg_type; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -654,11 +678,27 @@ struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; int i, j; + struct gsm_bts_role_bts *btsb; /* FIXME: allow multiple BTS */ bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); + btsb = bts_role_bts(bts); LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); +#ifdef ENABLE_LC15BTS + struct oml_alarm_list *ceased_alarm; + /*dispatch alarm signal */ + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_LOST_ALARM, &alarm_sig_data); + /* allocate new list of pending ceased alarm */ + ceased_alarm = talloc_zero(NULL, struct oml_alarm_list); + if (ceased_alarm) { + ceased_alarm->alarm_signal = S_NM_OML_PCU_CONN_LOST_ALARM; + /* add ceased alarm to pending list */ + llist_add(&ceased_alarm->list, &btsb->lc15.ceased_alarm_list); + LOGP(DPCU, LOGL_ERROR, "Alarm %d has added to pending ceased alarm list\n", ceased_alarm->alarm_signal); + } +#endif close(bfd->fd); bfd->fd = -1; diff --git a/src/common/rsl.c b/src/common/rsl.c index 490ae28..a31261b 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -50,6 +50,7 @@ #include #include #include +#include "osmo-bts/oml.h" //#define FAKE_CIPH_MODE_COMPL @@ -392,6 +393,19 @@ identity_lv, chan_needed); if (rc < 0) { /* FIXME: notfiy the BSC somehow ?*/ + switch (rc) { + /* Send Failure event report of BTS page table is full to BSC */ + case -ENOSPC: + if (trx) { + alarm_sig_data.mo = &trx->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_PAG_TBL_FULL_ALARM, &alarm_sig_data); + } + break; + + default: + break; + } + } pcu_tx_pag_req(identity_lv, chan_needed); @@ -1600,6 +1614,11 @@ LOGP(DRSL, LOGL_ERROR, "%s IPAC Failed to create RTP/RTCP sockets\n", gsm_lchan_name(lchan)); + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM, &alarm_sig_data); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } @@ -1629,6 +1648,11 @@ LOGP(DRSL, LOGL_ERROR, "%s IPAC Failed to bind RTP/RTCP sockets\n", gsm_lchan_name(lchan)); + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_RTP_BIND_ALARM, &alarm_sig_data); + osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); lchan->abis_ip.rtp_socket = NULL; msgb_queue_flush(&lchan->dl_tch_queue); @@ -1642,6 +1666,12 @@ LOGP(DRSL, LOGL_ERROR, "%s Rx RSL IPAC MDCX, " "but we have no RTP socket!\n", gsm_lchan_name(lchan)); + + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_NO_RTP_SOCK_ALARM, &alarm_sig_data); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } diff --git a/src/osmo-bts-litecell15/calib_file.c b/src/osmo-bts-litecell15/calib_file.c index 0714bc9..3aa5905 100644 --- a/src/osmo-bts-litecell15/calib_file.c +++ b/src/osmo-bts-litecell15/calib_file.c @@ -41,6 +41,7 @@ #include "l1_if.h" #include "lc15bts.h" #include "utils.h" +#include "osmo-bts/oml.h" /* Maximum calibration data chunk size */ #define MAX_CALIB_TBL_SIZE 65536 @@ -148,12 +149,19 @@ snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname); fname[sizeof(fname)-1] = '\0'; - st->fp = fopen(fname, "rb"); - if (!st->fp) { - LOGP(DL1C, LOGL_ERROR, - "Failed to open '%s' for calibration data.\n", fname); - return -1; - } + st->fp = fopen(fname, "rb"); + if (!st->fp) { + LOGP(DL1C, LOGL_NOTICE, "Failed to open '%s' for calibration data.\n", fname); + + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + alarm_sig_data.add_text = (char*)&fname[0]; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM, &alarm_sig_data); + } + return -1; + } return 0; } @@ -235,8 +243,18 @@ } rc = calib_verify(fl1h, desc); - if ( rc < 0 ) { - LOGP(DL1C, LOGL_ERROR, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc); + if (rc < 0) { + LOGP(DL1C, LOGL_NOTICE,"Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc); + + if (fl1h->phy_inst->trx) { + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + alarm_sig_data.add_text = (char*)&desc->fname[0]; + memcpy(alarm_sig_data.spare, &rc, sizeof(int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, &alarm_sig_data); + } + st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx); if (st->last_file_idx >= 0) @@ -289,10 +307,17 @@ struct calib_send_state *st = &fl1h->st; char *calib_path = fl1h->phy_inst->u.lc15.calib_path; - if (!calib_path) { - LOGP(DL1C, LOGL_ERROR, "Calibration file path not specified\n"); - return -1; - } + if (!calib_path) { + LOGP(DL1C, LOGL_NOTICE, "Calibration file path not specified\n"); + + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_NO_CALIB_PATH_ALARM, &alarm_sig_data); + } + return -1; + } rc = get_next_calib_file_idx(fl1h, -1); if (rc < 0) { diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index e0000a2..4137032 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -66,6 +66,7 @@ #include "misc/lc15bts_par.h" #include "misc/lc15bts_bid.h" #include "utils.h" +#include "osmo-bts/oml.h" extern unsigned int dsp_trace; @@ -548,7 +549,10 @@ break; default: LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", - l1sap->u.info.type); + l1sap->u.info.type); + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->u.info.type, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -574,6 +578,10 @@ default: LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n", l1sap->oph.primitive, l1sap->oph.operation); + + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->oph.primitive, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -1438,6 +1446,7 @@ if (!fl1h) return NULL; INIT_LLIST_HEAD(&fl1h->wlc_list); + INIT_LLIST_HEAD(&fl1h->alarm_list); fl1h->phy_inst = pinst; fl1h->dsp_trace_f = pinst->u.lc15.dsp_trace_f; @@ -1486,16 +1495,43 @@ struct gsm_bts_trx *trx = fl1h->phy_inst->trx; struct msgb *msg = sysp_msgb_alloc(); int rc; + struct oml_alarm_list *alarm_sent; Litecell15_Prim_t *sys_prim = msgb_sysprim(msg); sys_prim->id = Litecell15_PrimId_IsAliveReq; if (fl1h->hw_alive.dsp_alive_cnt == 0) { + /* check for the alarm has already sent or not */ + llist_for_each_entry(alarm_sent, &fl1h->alarm_list, list) { + llist_del(&alarm_sent->list); + if (alarm_sent->alarm_signal != S_NM_OML_BTS_DSP_ALIVE_ALARM) + continue; + + LOGP(DL1C, LOGL_ERROR, "Alarm %d has removed from sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr); + exit(23); + } LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n", get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr); - exit(23); + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + memcpy(alarm_sig_data.spare, &sys_prim->id, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_DSP_ALIVE_ALARM, &alarm_sig_data); + if (!alarm_sig_data.rc) { + /* allocate new list of sent alarms */ + alarm_sent = talloc_zero(fl1h, struct oml_alarm_list); + if (!alarm_sent) + return -EIO; + + alarm_sent->alarm_signal = S_NM_OML_BTS_DSP_ALIVE_ALARM; + /* add alarm to sent list */ + llist_add(&alarm_sent->list, &fl1h->alarm_list); + LOGP(DL1C, LOGL_ERROR, "Alarm %d has added to sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr); + } + } } LOGP(DL1C, LOGL_NOTICE, "Tx SYS prim %s (%d)\n", diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 8a7b737..f3ac3d3 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -38,6 +38,7 @@ uint32_t hLayer1; /* handle to the L1 instance in the DSP */ uint32_t dsp_trace_f; /* currently operational DSP trace flags */ struct llist_head wlc_list; + struct llist_head alarm_list; /* list of sent alarms */ struct phy_instance *phy_inst; -- To view, visit https://gerrit.osmocom.org/809 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic4e088a3af115d3d5a124b61c1e92eed277d3469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:07:54 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:07:54 +0000 Subject: [PATCH] osmo-bts[master]: LC15: Allow BTS to forward PCU failure alarms to network Message-ID: Review at https://gerrit.osmocom.org/810 LC15: Allow BTS to forward PCU failure alarms to network Change-Id: I39bb8f8b749e94394909aa4a4be000c306ed712a --- M include/osmo-bts/oml.h M include/osmo-bts/pcuif_proto.h M src/common/oml.c M src/common/pcu_sock.c 4 files changed, 44 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/10/810/1 diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index b3ccf9d..fb49078 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -27,6 +27,7 @@ S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM, S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, S_NM_OML_BTS_NO_CALIB_PATH_ALARM, + S_NM_OML_BTS_RX_PCU_FAIL_EVT_ALARM, }; struct oml_fail_evt_rep_sig_data { diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h index 5527238..b961229 100644 --- a/include/osmo-bts/pcuif_proto.h +++ b/include/osmo-bts/pcuif_proto.h @@ -14,6 +14,9 @@ #define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */ #define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */ +/*alarms & performance counters */ +#define PCU_IF_MSG_FAILURE_EVT_IND 0x61 /* PCU failure event report indication*/ + /* sapi */ #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ #define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */ @@ -136,6 +139,14 @@ uint8_t identity_lv[9]; } __attribute__ ((packed)); +struct gsm_pcu_if_fail_evt_ind { + uint8_t event_type; + uint8_t event_serverity; + uint8_t cause_type; + uint16_t event_cause; + char add_text[100]; +}__attribute__ ((packed)); + struct gsm_pcu_if { /* context based information */ uint8_t msg_type; /* message type */ @@ -152,6 +163,7 @@ struct gsm_pcu_if_act_req act_req; struct gsm_pcu_if_time_ind time_ind; struct gsm_pcu_if_pag_req pag_req; + struct gsm_pcu_if_fail_evt_ind failure_evt_ind; } u; } __attribute__ ((packed)); diff --git a/src/common/oml.c b/src/common/oml.c index 924c4dc..13a4799 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -1552,6 +1552,14 @@ sig_data->add_text); break; + case S_NM_OML_BTS_RX_PCU_FAIL_EVT_ALARM: + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + sig_data->event_type, + sig_data->event_serverity, + sig_data->cause_type, + sig_data->event_cause, + sig_data->add_text); + break; default: break; } diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index bd50be1..78c5fe8 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -604,6 +604,26 @@ return 0; } +static int pcu_rx_failure_event_rep(struct gsm_bts *bts, struct gsm_pcu_if_fail_evt_ind *fail_ind) +{ + LOGP(DPCU, LOGL_DEBUG, "[PCU] Failure EVT REP detailed: evt_type=%02x, evt_serv=%02x, cause_type=%02x, cause_id=%04x, text=%s\n", + fail_ind->event_type, + fail_ind->event_serverity, + fail_ind->cause_type, + fail_ind->event_cause, + fail_ind->add_text); + + alarm_sig_data.mo = &bts->gprs.cell.mo; + alarm_sig_data.event_type = fail_ind->event_type; + alarm_sig_data.event_serverity = fail_ind->event_serverity; + alarm_sig_data.cause_type = fail_ind->cause_type; + alarm_sig_data.event_cause = fail_ind->event_cause; + alarm_sig_data.add_text = &fail_ind->add_text[0]; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_PCU_FAIL_EVT_ALARM, &alarm_sig_data); + + return alarm_sig_data.rc; +} + static int pcu_rx(struct gsm_network *net, uint8_t msg_type, struct gsm_pcu_if *pcu_prim) { @@ -621,6 +641,9 @@ case PCU_IF_MSG_ACT_REQ: rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req); break; + case PCU_IF_MSG_FAILURE_EVT_IND: + rc = pcu_rx_failure_event_rep(bts, &pcu_prim->u.failure_evt_ind); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); -- To view, visit https://gerrit.osmocom.org/810 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I39bb8f8b749e94394909aa4a4be000c306ed712a Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:07:54 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:07:54 +0000 Subject: [PATCH] osmo-bts[master]: LC15: Implementation of TS 12.21 measurement related message... Message-ID: Review at https://gerrit.osmocom.org/811 LC15: Implementation of TS 12.21 measurement related messages to measure PCU KPI Change-Id: I352600f964e6c161b9259c62f2e0a0f39f0f60d9 --- M include/osmo-bts/oml.h M include/osmo-bts/pcu_if.h M include/osmo-bts/pcuif_proto.h M src/common/oml.c M src/common/pcu_sock.c 5 files changed, 594 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/11/811/1 diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index fb49078..2751108 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -1,5 +1,6 @@ #ifndef _OML_H #define _OML_H +#include #include "openbsc/signal.h" struct gsm_bts; @@ -28,6 +29,9 @@ S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, S_NM_OML_BTS_NO_CALIB_PATH_ALARM, S_NM_OML_BTS_RX_PCU_FAIL_EVT_ALARM, + S_NM_OML_BTS_UNKN_START_MEAS_REQ_ALARM, + S_NM_OML_BTS_UNKN_STOP_MEAS_REQ_ALARM, + S_NM_OML_BTS_UNKN_MEAS_REQ_ALARM, }; struct oml_fail_evt_rep_sig_data { @@ -46,9 +50,27 @@ uint16_t alarm_signal; /* Failure alarm report signal cause */ }; +enum abis_nm_msgtype_ipacc_appended { + NM_MT_IPACC_START_MEAS_ACK = 0xde, + NM_MT_IPACC_MEAS_RES_REQ_NACK = 0xfc, + NM_MT_IPACC_START_MEAS_NACK = 0xfd, + NM_MT_IPACC_STOP_MEAS_ACK = 0xdf, + NM_MT_IPACC_STOP_MEAS_NACK = 0xfe, +}; + +enum abis_nm_ipacc_meas_type { + NM_IPACC_MEAS_TYPE_CCCH = 0x45, + NM_IPACC_MEAS_TYPE_UL_TBF = 0x49, + NM_IPACC_MEAS_TYPE_DL_TBF = 0x4a, + NM_IPACC_MEAS_TYPE_TBF_USE = 0x4c, + NM_IPACC_MEAS_TYPE_LLC_USE = 0x4d, + NM_IPACC_MEAS_TYPE_CS_CHG = 0x50, + NM_IPACC_MEAS_TYPE_UNKN +}; + enum abis_nm_failure_event_causes { /* Critical causes */ - NM_EVT_CAUSE_CRIT_SW_FATAL = 0x3000, + NM_EVT_CAUSE_CRIT_SW_FATAL = 0x3000, NM_EVT_CAUSE_CRIT_DSP_FATAL = 0x3001, NM_EVT_CAUSE_CRIT_PROC_STOP = 0x3006, NM_EVT_CAUSE_CRIT_RTP_CREATE_FAIL = 0x332a, @@ -56,18 +78,21 @@ NM_EVT_CAUSE_CRIT_RTP_NO_SOCK = 0x332c, NM_EVT_CAUSE_CRIT_BAD_CALIB_PATH = 0x3401, NM_EVT_CAUSE_CRIT_OPEN_CALIB_FAIL = 0x3403, - NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL = 0x3404, + NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL = 0x3404, /* Major causes */ NM_EVT_CAUSE_MAJ_UKWN_PCU_MSG = 0x3002, NM_EVT_CAUSE_MAJ_UKWN_DL_MSG = 0x3003, NM_EVT_CAUSE_MAJ_UKWN_UL_MSG = 0x3004, NM_EVT_CAUSE_MAJ_UKWN_MPH_MSG = 0x3005, - NM_EVT_CAUSE_MAJ_RSL_FAIL = 0x3309, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_START_MSG = 0x3007, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_REQ_MSG = 0x3008, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_STOP_MSG = 0x3009, + NM_EVT_CAUSE_MAJ_RSL_FAIL = 0x3309, NM_EVT_CAUSE_MAJ_DEACT_RF_FAIL = 0x330a, /* Minor causes */ NM_EVT_CAUSE_MIN_PAG_TAB_FULL = 0x3402, /* Warning causes */ - NM_EVT_CAUSE_WARN_SW_WARN = 0x0001, + NM_EVT_CAUSE_WARN_SW_WARN = 0x0001, }; @@ -114,4 +139,10 @@ /* Initialize failure report signalling */ int oml_failure_report_init(void *handler); +/* NM measurement related messages */ +int oml_tx_nm_start_meas_ack_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause); +int oml_tx_nm_meas_res_req_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause); +int oml_tx_nm_meas_res_resp(struct gsm_abis_mo *mo, struct gsm_pcu_if_meas_resp meas_resp); +int oml_tx_nm_stop_meas_ack_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause); + #endif // _OML_H */ diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h index a020c05..298c1dc 100644 --- a/include/osmo-bts/pcu_if.h +++ b/include/osmo-bts/pcu_if.h @@ -4,6 +4,7 @@ #define PCU_SOCK_DEFAULT "/tmp/pcu_bts" extern int pcu_direct; +extern int pcu_start_meas_flags; int pcu_tx_info_ind(void); int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, @@ -22,4 +23,8 @@ bool pcu_connected(void); +int pcu_tx_nm_start_meas(struct gsm_bts *bts, uint8_t meas_id, uint8_t ack_flag); +int pcu_tx_nm_meas_res_req(struct gsm_bts *bts, uint8_t meas_id); +int pcu_tx_nm_stop_meas(struct gsm_bts *bts, uint8_t meas_id); + #endif /* _PCU_IF_H */ diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h index b961229..c79084e 100644 --- a/include/osmo-bts/pcuif_proto.h +++ b/include/osmo-bts/pcuif_proto.h @@ -1,5 +1,6 @@ #ifndef _PCUIF_PROTO_H #define _PCUIF_PROTO_H +#include #define PCU_IF_VERSION 0x07 @@ -16,6 +17,15 @@ /*alarms & performance counters */ #define PCU_IF_MSG_FAILURE_EVT_IND 0x61 /* PCU failure event report indication*/ +#define PCU_IF_MSG_START_MEAS_REQ 0x62 /* PCU start measurement request */ +#define PCU_IF_MSG_START_MEAS_ACK 0x63 /* PCU start measurement ACK */ +#define PCU_IF_MSG_START_MEAS_NACK 0x64 /* PCU start measurement NACK */ +#define PCU_IF_MSG_MEAS_RES_REQ 0x65 /* PCU measurement result request*/ +#define PCU_IF_MSG_MEAS_RES_RESP 0x66 /* PCU measurement result response*/ +#define PCU_IF_MSG_MEAS_RES_NACK 0x67 /* PCU measurement result NACK*/ +#define PCU_IF_MSG_STOP_MEAS_REQ 0x68 /* PCU stop measurement request */ +#define PCU_IF_MSG_STOP_MEAS_ACK 0x69 /* PCU stop measurement ACK */ +#define PCU_IF_MSG_STOP_MEAS_NACK 0x6a /* PCU stop measurement NACK */ /* sapi */ #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ @@ -42,6 +52,14 @@ #define PCU_IF_FLAG_MCS7 (1 << 26) #define PCU_IF_FLAG_MCS8 (1 << 27) #define PCU_IF_FLAG_MCS9 (1 << 28) + +/* PCU start measurement flags */ +#define PCU_IF_FLAG_START_MEAS_CCCH (1 << 0) +#define PCU_IF_FLAG_START_MEAS_UL_TBF (1 << 1) +#define PCU_IF_FLAG_START_MEAS_DL_TBF (1 << 2) +#define PCU_IF_FLAG_START_MEAS_TBF_USE (1 << 3) +#define PCU_IF_FLAG_START_MEAS_LLC_USE (1 << 4) +#define PCU_IF_FLAG_START_MEAS_CS_CHG (1 << 5) struct gsm_pcu_if_data { uint8_t sapi; @@ -147,6 +165,24 @@ char add_text[100]; }__attribute__ ((packed)); +struct gsm_pcu_if_start_meas_req { + uint8_t meas_id; /*measurement ID */ + uint8_t nack_cause; + uint8_t spare[2]; +}__attribute__ ((packed)); + +struct gsm_pcu_if_meas_req { + uint8_t meas_id; /*measurement ID */ + uint8_t spare[2]; +}__attribute__ ((packed)); + +struct gsm_pcu_if_meas_resp { + uint8_t meas_id; /*measurement ID */ + uint8_t nack_cause; /*NACK cause */ + uint16_t len; /*total result length */ + uint8_t data[100]; /*PM counter result must be started from here */ +}__attribute__ ((packed)); + struct gsm_pcu_if { /* context based information */ uint8_t msg_type; /* message type */ @@ -164,6 +200,10 @@ struct gsm_pcu_if_time_ind time_ind; struct gsm_pcu_if_pag_req pag_req; struct gsm_pcu_if_fail_evt_ind failure_evt_ind; + struct gsm_pcu_if_start_meas_req start_meas_req; + struct gsm_pcu_if_start_meas_req stop_meas_req; + struct gsm_pcu_if_meas_req meas_req; + struct gsm_pcu_if_meas_resp meas_resp; } u; } __attribute__ ((packed)); diff --git a/src/common/oml.c b/src/common/oml.c index 13a4799..29cba5a 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -94,6 +94,9 @@ [NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V }, [NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V }, [NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V }, + /* GSM 12.21 attributes */ + [NM_ATT_MEAS_TYPE] = { TLV_TYPE_TV }, + [NM_ATT_MEAS_RES] = { TLV_TYPE_TV }, }, }; @@ -404,6 +407,81 @@ } return oml_mo_send_msg(mo, nmsg, NM_MT_FAILURE_EVENT_REP); +} + +/* TS 12.21 8.10.2 */ +int oml_tx_nm_meas_res_resp(struct gsm_abis_mo *mo, struct gsm_pcu_if_meas_resp meas_resp) +{ + struct msgb *nmsg; + + LOGP(DOML, LOGL_INFO, "%s Tx MEASurement RESult RESPonse\n", gsm_abis_mo_name(mo)); + + nmsg = oml_msgb_alloc(); + if (!nmsg) + return -ENOMEM; + + msgb_tv_put(nmsg, NM_ATT_MEAS_TYPE, meas_resp.meas_id); + msgb_tl16v_put(nmsg, NM_ATT_MEAS_RES, meas_resp.len, meas_resp.data); + + return oml_mo_send_msg(mo, nmsg, NM_MT_MEAS_RES_RESP); +} + +int oml_tx_nm_start_meas_ack_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause) +{ + struct msgb *msg; + uint8_t msg_type; + + msg = oml_msgb_alloc(); + if (!msg) + return -ENOMEM; + + if (nack_cause) { + msg_type = NM_MT_IPACC_START_MEAS_NACK; + msgb_tv_put(msg, NM_ATT_NACK_CAUSES, nack_cause); + msgb_tv_put(msg, NM_ATT_MEAS_TYPE, meas_id); + } else { + msg_type = NM_MT_IPACC_START_MEAS_ACK; + msgb_tv_put(msg, NM_ATT_MEAS_TYPE, meas_id); + } + + return oml_mo_send_msg(mo, msg, msg_type); +} + +int oml_tx_nm_stop_meas_ack_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause) +{ + struct msgb *msg; + uint8_t msg_type; + + msg = oml_msgb_alloc(); + if (!msg) + return -ENOMEM; + + if (nack_cause) { + msg_type = NM_MT_IPACC_STOP_MEAS_NACK; + msgb_tv_put(msg, NM_ATT_NACK_CAUSES, nack_cause); + msgb_tv_put(msg, NM_ATT_MEAS_TYPE, meas_id); + } else { + msg_type = NM_MT_IPACC_STOP_MEAS_ACK; + msgb_tv_put(msg, NM_ATT_MEAS_TYPE, meas_id); + } + + return oml_mo_send_msg(mo, msg, msg_type); +} + +int oml_tx_nm_meas_res_req_nack(struct gsm_abis_mo *mo, uint8_t meas_id, uint8_t nack_cause) +{ + struct msgb *msg; + uint8_t msg_type; + + msg = oml_msgb_alloc(); + if (!msg) + return -ENOMEM; + + msg_type = NM_MT_IPACC_MEAS_RES_REQ_NACK; + msgb_tv_put(msg, NM_ATT_NACK_CAUSES, nack_cause); + msgb_tv_put(msg, NM_ATT_MEAS_TYPE, meas_id); + + return oml_mo_send_msg(mo, msg, msg_type); } /* TS 12.21 9.4.53 */ @@ -941,6 +1019,226 @@ return bts_model_chg_adm_state(bts, mo, obj, adm_state); } +/* GSM 12.21 section 8.10.1 */ +static int oml_rx_nm_meas_res_req(struct gsm_bts *bts, struct msgb *msg) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_abis_mo *mo = &bts->gprs.cell.mo; + struct tlv_parsed tp; + int rc; + uint8_t meas_id; + + LOGP(DOML, LOGL_DEBUG, "%s Rx MEAS RES REQ\n", gsm_abis_mo_name(mo)); + + rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "New value for Attribute not supported\n"); + return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); + } + + if (!TLVP_PRESENT(&tp, NM_ATT_MEAS_TYPE)) { + LOGP(DOML, LOGL_NOTICE, "%s NM_ATT_MEAS_TYPE not found\n", gsm_abis_mo_name(mo)); + return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); + } + + /* Get measurement ID */ + meas_id = *TLVP_VAL(&tp, NM_ATT_MEAS_TYPE); + + /* Set start measurement ID flags*/ + switch(meas_id) { + case NM_IPACC_MEAS_TYPE_CCCH: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_CCCH; + break; + case NM_IPACC_MEAS_TYPE_UL_TBF: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_UL_TBF; + break; + case NM_IPACC_MEAS_TYPE_DL_TBF: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_DL_TBF; + break; + case NM_IPACC_MEAS_TYPE_TBF_USE: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_TBF_USE; + break; + case NM_IPACC_MEAS_TYPE_LLC_USE: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_LLC_USE; + break; + case NM_IPACC_MEAS_TYPE_CS_CHG: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_CS_CHG; + break; + default: + LOGP(DOML, LOGL_NOTICE, "%s Unsupported NM START MEASurement type received 0x%02x\n", gsm_abis_mo_name(mo), meas_id); + + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_UNKN_MEAS_REQ_ALARM, &alarm_sig_data); + + /*send START MEAS NACK */ + return oml_tx_nm_start_meas_ack_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + /* send request to PCU */ + rc = pcu_tx_nm_meas_res_req(bts, meas_id); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "%s PCU socket may not be ready for measurement ID (%d)\n", gsm_abis_mo_name(mo), meas_id); + + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_NOT_AVAIL_ALARM, &alarm_sig_data); + + /*send MEAS RES REQ NACK */ + return oml_tx_nm_meas_res_req_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + return 0; +} + +/* GSM 12.21 section 8.10.3 */ +static int oml_rx_nm_start_meas(struct gsm_bts *bts, struct msgb *msg) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_abis_mo *mo = &bts->gprs.cell.mo; + struct tlv_parsed tp; + int rc; + uint8_t meas_id; + + LOGP(DOML, LOGL_DEBUG, "%s Rx START MEAS\n", gsm_abis_mo_name(mo)); + + rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "New value for Attribute not supported\n"); + return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); + } + + if (!TLVP_PRESENT(&tp, NM_ATT_MEAS_TYPE)) { + LOGP(DOML, LOGL_NOTICE, "New value for Attribute not supported\n"); + return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); + } + + /* Get measurement ID */ + meas_id = *TLVP_VAL(&tp, NM_ATT_MEAS_TYPE); + + /* Set start measurement ID flags*/ + switch(meas_id) { + case NM_IPACC_MEAS_TYPE_CCCH: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_CCCH; + break; + case NM_IPACC_MEAS_TYPE_UL_TBF: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_UL_TBF; + break; + case NM_IPACC_MEAS_TYPE_DL_TBF: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_DL_TBF; + break; + case NM_IPACC_MEAS_TYPE_TBF_USE: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_TBF_USE; + break; + case NM_IPACC_MEAS_TYPE_LLC_USE: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_LLC_USE; + break; + case NM_IPACC_MEAS_TYPE_CS_CHG: + pcu_start_meas_flags |= PCU_IF_FLAG_START_MEAS_CS_CHG; + break; + default: + LOGP(DOML, LOGL_NOTICE, "%s Unsupported NM START MEASurement type received 0x%02x\n", gsm_abis_mo_name(mo), meas_id); + + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_UNKN_START_MEAS_REQ_ALARM, &alarm_sig_data); + + /*send START MEAS NACK */ + return oml_tx_nm_start_meas_ack_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + /* send request to PCU */ + rc = pcu_tx_nm_start_meas(bts, meas_id, 0); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "%s PCU socket may not be ready\n", gsm_abis_mo_name(mo)); + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_NOT_AVAIL_ALARM, &alarm_sig_data); + + /*send START MEAS NACK */ + return oml_tx_nm_start_meas_ack_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + return 0; +} + +static int oml_rx_nm_stop_meas(struct gsm_bts *bts, struct msgb *msg) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_abis_mo *mo = &bts->gprs.cell.mo; + struct tlv_parsed tp; + int rc; + uint8_t meas_id; + + LOGP(DOML, LOGL_DEBUG, "%s Rx STOP MEAS\n", gsm_abis_mo_name(mo)); + + rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "New value for Attribute not supported\n"); + return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); + } + + if (!TLVP_PRESENT(&tp, NM_ATT_MEAS_TYPE)) { + LOGP(DOML, LOGL_NOTICE, "New value for Attribute not supported\n"); + return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); + } + + /* Get measurement ID */ + meas_id = *TLVP_VAL(&tp, NM_ATT_MEAS_TYPE); + + /* Validate measurement ID */ + switch(meas_id) { + case NM_IPACC_MEAS_TYPE_CCCH: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_CCCH; + break; + case NM_IPACC_MEAS_TYPE_UL_TBF: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_UL_TBF; + break; + case NM_IPACC_MEAS_TYPE_DL_TBF: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_DL_TBF; + break; + case NM_IPACC_MEAS_TYPE_TBF_USE: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_TBF_USE; + break; + case NM_IPACC_MEAS_TYPE_LLC_USE: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_LLC_USE; + break; + case NM_IPACC_MEAS_TYPE_CS_CHG: + pcu_start_meas_flags &= ~PCU_IF_FLAG_START_MEAS_CS_CHG; + break; + default: + LOGP(DOML, LOGL_NOTICE, "%s Unsupported NM STOP MEASurement type received 0x%02x\n", gsm_abis_mo_name(mo), meas_id); + + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_UNKN_STOP_MEAS_REQ_ALARM, &alarm_sig_data); + + /*send START MEAS NACK */ + return oml_tx_nm_start_meas_ack_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + /* send request to PCU */ + rc = pcu_tx_nm_stop_meas(bts, meas_id); + if (rc < 0) { + LOGP(DOML, LOGL_NOTICE, "%s PCU socket may not be ready\n", gsm_abis_mo_name(mo)); + + /*send alarm to indicate PCU link is not ready */ + alarm_sig_data.mo = mo; + alarm_sig_data.spare[0] = meas_id; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_NOT_AVAIL_ALARM, &alarm_sig_data); + + /*send STOP MEAS NACK */ + return oml_tx_nm_stop_meas_ack_nack(mo, meas_id, NM_NACK_NOTH_REPORT_EXIST); + } + + return 0; +} + static int down_fom(struct gsm_bts *bts, struct msgb *msg) { struct abis_om_fom_hdr *foh = msgb_l3(msg); @@ -983,6 +1281,15 @@ break; case NM_MT_IPACC_SET_ATTR: ret = oml_ipa_set_attr(bts, msg); + break; + case NM_MT_START_MEAS: + ret = oml_rx_nm_start_meas(bts, msg); + break; + case NM_MT_MEAS_RES_REQ: + ret = oml_rx_nm_meas_res_req(bts, msg); + break; + case NM_MT_STOP_MEAS: + ret = oml_rx_nm_stop_meas(bts, msg); break; default: LOGP(DOML, LOGL_INFO, "unknown Formatted O&M msg_type 0x%02x\n", @@ -1560,6 +1867,43 @@ sig_data->event_cause, sig_data->add_text); break; + + case S_NM_OML_BTS_UNKN_START_MEAS_REQ_ALARM: + snprintf(log_msg, 100, "Unsupported START MEASurement ID (0x%02x)\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_START_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_UNKN_STOP_MEAS_REQ_ALARM: + snprintf(log_msg, 100, "Unsupported STOP MEASurement ID (0x%02x)\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_STOP_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_UNKN_MEAS_REQ_ALARM: + snprintf(log_msg, 100, "Unsupported MEASurement REQuest ID (0x%02x)\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_MEAS_REQ_MSG, + sig_data->add_text); + break; + default: break; } diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 78c5fe8..8aec856 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -47,6 +47,7 @@ extern struct gsm_network bts_gsmnet; int pcu_direct = 0; +int pcu_start_meas_flags = 0; static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0}; static const char *sapi_string[] = { @@ -132,7 +133,7 @@ struct gsm_bts_gprs_nsvc *nsvc; struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; - int i, j, rc; + int i, j, rc, meas_id; struct gsm_bts_role_bts *btsb; LOGP(DPCU, LOGL_INFO, "Sending info\n"); @@ -251,6 +252,43 @@ rc = pcu_sock_send(net, msg); if (rc < 0) return rc; + /* send pending start measurement messages to PCU */ + for(i = 0; i < 32; i++) { + + meas_id = pcu_start_meas_flags & (1 << i); + if(!meas_id) + continue; + + /* decode start measurement flags */ + switch (meas_id) { + case PCU_IF_FLAG_START_MEAS_CCCH: + meas_id = NM_IPACC_MEAS_TYPE_CCCH; + break; + case PCU_IF_FLAG_START_MEAS_UL_TBF: + meas_id = NM_IPACC_MEAS_TYPE_UL_TBF; + break; + case PCU_IF_FLAG_START_MEAS_DL_TBF: + meas_id = NM_IPACC_MEAS_TYPE_DL_TBF; + break; + case PCU_IF_FLAG_START_MEAS_TBF_USE: + meas_id = NM_IPACC_MEAS_TYPE_TBF_USE; + break; + case PCU_IF_FLAG_START_MEAS_LLC_USE: + meas_id = NM_IPACC_MEAS_TYPE_LLC_USE; + break; + case PCU_IF_FLAG_START_MEAS_CS_CHG: + meas_id = NM_IPACC_MEAS_TYPE_CS_CHG; + break; + default: + meas_id = NM_IPACC_MEAS_TYPE_UNKN; + break; + } + + /* send request to PCU */ + rc = pcu_tx_nm_start_meas(bts, meas_id, 1); + if (rc < 0) + return rc; + } #ifdef ENABLE_LC15BTS struct oml_alarm_list *ceased_alarm; @@ -500,6 +538,65 @@ return pcu_sock_send(&bts_gsmnet, msg); } +int pcu_tx_nm_start_meas(struct gsm_bts *bts, uint8_t meas_id, uint8_t ack_flag) +{ + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_start_meas_req *start_meas_req; + struct msgb *msg; + + msg = pcu_msgb_alloc(PCU_IF_MSG_START_MEAS_REQ, bts->nr); + if (!msg) + return -ENOMEM; + + pcu_prim = (struct gsm_pcu_if *) msg->data; + start_meas_req = &pcu_prim->u.start_meas_req; + start_meas_req->meas_id = meas_id; + start_meas_req->spare[0] = ack_flag; + + LOGP(DPCU, LOGL_INFO, "[BTS->PCU] Sent START MEASurement REQuest: 0x%02x\n", start_meas_req->meas_id); + + return pcu_sock_send(&bts_gsmnet, msg); +} + +int pcu_tx_nm_stop_meas(struct gsm_bts *bts, uint8_t meas_id) +{ + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_start_meas_req *stop_meas_req; + struct msgb *msg; + + msg = pcu_msgb_alloc(PCU_IF_MSG_STOP_MEAS_REQ, bts->nr); + if (!msg) + return -ENOMEM; + + pcu_prim = (struct gsm_pcu_if *) msg->data; + stop_meas_req = &pcu_prim->u.start_meas_req; + stop_meas_req->meas_id = meas_id; + + LOGP(DPCU, LOGL_INFO, "[BTS->PCU] Sent STOP MEASurement REQuest: 0x%02x\n", stop_meas_req->meas_id); + + return pcu_sock_send(&bts_gsmnet, msg); +} + +int pcu_tx_nm_meas_res_req(struct gsm_bts *bts, uint8_t meas_id) +{ + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_meas_req *meas_req; + struct msgb *msg; + + msg = pcu_msgb_alloc(PCU_IF_MSG_MEAS_RES_REQ, bts->nr); + if (!msg) + return -ENOMEM; + + pcu_prim = (struct gsm_pcu_if *) msg->data; + meas_req = &pcu_prim->u.meas_req; + meas_req->meas_id = meas_id; + + LOGP(DPCU, LOGL_INFO, "[BTS->PCU ]Sent MEASurement RESult REQuest: 0x%02x\n", meas_req->meas_id); + + return pcu_sock_send(&bts_gsmnet, msg); +} + + static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, struct gsm_pcu_if_data *data_req) { @@ -624,6 +721,60 @@ return alarm_sig_data.rc; } +static int pcu_rx_nm_start_meas_ack_nack(struct gsm_bts *bts, struct gsm_pcu_if_start_meas_req *start_meas, uint8_t nack_cause) +{ + int rc; + + /* don't send ACK/NACK to MSS if BTS does not request send ACK/NACK */ + if (start_meas->spare[0]) + return 0; + + rc = oml_tx_nm_start_meas_ack_nack(&bts->gprs.cell.mo, start_meas->meas_id, nack_cause); + if (rc < 0 ) + return rc; + + return 0; +} + +static int pcu_rx_nm_stop_meas_ack_nack(struct gsm_bts *bts, struct gsm_pcu_if_start_meas_req *stop_meas, uint8_t nack_cause) +{ + int rc; + + rc = oml_tx_nm_stop_meas_ack_nack(&bts->gprs.cell.mo, stop_meas->meas_id, nack_cause); + if (rc < 0 ) + return rc; + + return 0; +} + +static int pcu_rx_nm_meas_res_req_nack(struct gsm_bts *bts, struct gsm_pcu_if_meas_resp *meas_resp, uint8_t nack_cause) +{ + int rc; + + rc = oml_tx_nm_meas_res_req_nack(&bts->gprs.cell.mo, meas_resp->meas_id, nack_cause); + if (rc < 0 ) + return rc; + + return 0; +} + +static int pcu_rx_nm_meas_res_resp(struct gsm_bts *bts, struct gsm_pcu_if_meas_resp *meas_resp) +{ + struct gsm_pcu_if_meas_resp res_resp; + int rc; + + res_resp.meas_id = meas_resp->meas_id; + res_resp.len = meas_resp->len; + memcpy(res_resp.data, meas_resp->data, meas_resp->len); + + rc = oml_tx_nm_meas_res_resp(&bts->gprs.cell.mo, res_resp); + if (rc < 0 ) + return rc; + + return 0; +} + + static int pcu_rx(struct gsm_network *net, uint8_t msg_type, struct gsm_pcu_if *pcu_prim) { @@ -644,6 +795,24 @@ case PCU_IF_MSG_FAILURE_EVT_IND: rc = pcu_rx_failure_event_rep(bts, &pcu_prim->u.failure_evt_ind); break; + case PCU_IF_MSG_START_MEAS_ACK: + rc = pcu_rx_nm_start_meas_ack_nack(bts, &pcu_prim->u.start_meas_req, 0); + break; + case PCU_IF_MSG_START_MEAS_NACK: + rc = pcu_rx_nm_start_meas_ack_nack(bts, &pcu_prim->u.start_meas_req, pcu_prim->u.start_meas_req.nack_cause); + break; + case PCU_IF_MSG_MEAS_RES_NACK: + rc = pcu_rx_nm_meas_res_req_nack(bts, &pcu_prim->u.meas_resp, pcu_prim->u.meas_resp.nack_cause); + break; + case PCU_IF_MSG_MEAS_RES_RESP: + rc = pcu_rx_nm_meas_res_resp(bts, &pcu_prim->u.meas_resp); + break; + case PCU_IF_MSG_STOP_MEAS_ACK: + rc = pcu_rx_nm_stop_meas_ack_nack(bts, &pcu_prim->u.stop_meas_req, 0); + break; + case PCU_IF_MSG_STOP_MEAS_NACK: + rc = pcu_rx_nm_stop_meas_ack_nack(bts, &pcu_prim->u.stop_meas_req, pcu_prim->u.stop_meas_req.nack_cause); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); -- To view, visit https://gerrit.osmocom.org/811 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I352600f964e6c161b9259c62f2e0a0f39f0f60d9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:08:33 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:08:33 +0000 Subject: [PATCH] libosmocore[master]: IPAC manufacture-defined measurement pre-processing definitions Message-ID: Review at https://gerrit.osmocom.org/812 IPAC manufacture-defined measurement pre-processing definitions Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b --- M include/osmocom/gsm/protocol/gsm_08_58.h M src/gsm/rsl.c 2 files changed, 126 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/12/812/1 diff --git a/include/osmocom/gsm/protocol/gsm_08_58.h b/include/osmocom/gsm/protocol/gsm_08_58.h index 03337e7..f2d3b2d 100644 --- a/include/osmocom/gsm/protocol/gsm_08_58.h +++ b/include/osmocom/gsm/protocol/gsm_08_58.h @@ -170,6 +170,9 @@ RSL_MT_IPAC_DISC_MUX = 0x56, RSL_MT_IPAC_DISC_MUX_ACK, RSL_MT_IPAC_DISC_MUX_NACK, + RSL_MT_IPAC_MEAS_PREPROC_DFT = 0x60, /*Extented Common Channel Management */ + RSL_MT_IPAC_HO_CAN_ENQ = 0x61, + RSL_MT_IPAC_HO_CAN_RES = 0x62, RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */ RSL_MT_IPAC_CRCX_ACK, RSL_MT_IPAC_CRCX_NACK, @@ -295,6 +298,41 @@ RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe, }; +/* IPAC MEAS_PREPROC AVERAGING METHOD */ +enum { + IPAC_UNWEIGHTED_AVE = 0, + IPAC_WEIGHTED_AVE, + IPAC_MEDIAN_AVE +}; + +/* IPAC MEAS_PREPROC AVERAGING PARAMID */ +enum { + IPAC_RXLEV_AVE = 0, + IPAC_RXQUAL_AVE, + IPAC_MS_BTS_DIS_AVE +}; + +/* IPAC MEAS_PREPROC HO CAUSES */ +enum { + IPAC_HO_RQD_CAUSE_L_RXLEV_UL_H = 0x01, + IPAC_HO_RQD_CAUSE_L_RXLEV_DL_H, + IPAC_HO_RQD_CAUSE_L_RXQUAL_UL_H, + IPAC_HO_RQD_CAUSE_L_RXQUAL_DL_H, + IPAC_HO_RQD_CAUSE_RXLEV_UL_IH, + IPAC_HO_RQD_CAUSE_RXLEV_DL_IH, + IPAC_HO_RQD_CAUSE_MAX_MS_RANGE, + IPAC_HO_RQD_CAUSE_POWER_BUDGET, + IPAC_HO_RQD_CAUSE_ENQUIRY, + IPAC_HO_RQD_CAUSE_ENQUIRY_FAILED, + IPAC_HO_RQD_CAUSE_NORMAL3G, + IPAC_HO_RQD_CAUSE_EMERGENCY3G, + IPAC_HO_RQD_CAUSE_SERVICE_PREFERRED3G, + IPAC_HO_RQD_CAUSE_O_M_SHUTDOWN, + IPAC_HO_RQD_CAUSE_QUALITY_PROMOTION, + IPAC_HO_RQD_CAUSE_LOAD_PROMOTION, + IPAC_HO_RQD_CAUSE_LOAD_DEMOTION, + IPAC_HO_RQD_CAUSE_MAX, +}; /* Chapter 9.3.1 */ #define RSL_CHAN_NR_MASK 0xf8 #define RSL_CHAN_NR_1 0x08 /*< bit to add for 2nd,... lchan */ @@ -603,6 +641,89 @@ RSL_IPAC_EIE_NCELL_LIST_EXT = 0x13, RSL_IPAC_EIE_MASTER_KEY = 0x14, RSL_IPAC_EIE_MASTER_SALT = 0x15, + /* additional IPAC measurement pre-processing related IEI */ + RSL_IPAC_EIE_MEAS_TRANS_RES = 0x16, + RSL_IPAC_EIE_3G_HO_PARAM = 0x17, + RSL_IPAC_EIE_3G_NCELL_LIST = 0x18, + RSL_IPAC_EIE_SDCCH_CTL_PARAM = 0x1a, + RSL_IPAC_EIE_AMR_CONV_THRESH = 0x1b, + +}; + +struct ipac_preproc_ave_cfg { + uint8_t h_reqave:5, + param_id:2, + reserved:1; + uint8_t h_reqt:5, + ave_method:3; +}__attribute__ ((packed)); + +struct ipac_preproc_ho_thresh { + uint8_t l_rxlev_ul_h:6, + reserved_l_rxlev_ul:2; + uint8_t l_rxlev_dl_h:6, + reserved_l_rxlev_dl:2; + uint8_t rxlev_ul_ih:6, + reserved_rxlev_ul:2; + uint8_t rxlev_dl_ih:6, + reserved_rxlev_dl:2; + uint8_t l_rxqual_ul_h:3, + reserved_rxlqual_ul:1, + l_rxqual_dl_h:3, + reserved_rxqual_dl:1; + uint8_t ms_range_max:6, + reserved_ms_range:2; +}__attribute__ ((packed)); + +struct ipac_preproc_ho_comp { + uint8_t p5:5, + reserved_p5:3; + uint8_t n5:5, + reserved_n5:3; + uint8_t p6:5, + reserved_p6:3; + uint8_t n6:5, + reserved_n6:3; + uint8_t p7:5, + reserved_p7:3; + uint8_t n7:5, + reserved_n7:3; + uint8_t p8:5, + reserved_p8:3; + uint8_t n8:5, + reserved_n8:3; + uint8_t ho_interval:5, + reserved_ho:3; + uint8_t reserved; + +}__attribute__ ((packed)); + +struct ipac_preproc_ho_candidates { + uint8_t bsic:6, + reserved0:2; + uint8_t bcch_freq:5, + ba_used:1, + s:1, + reserved1:1; +}__attribute__ ((packed)); + +struct ipac_preproc_ncell_dflts { + uint8_t rxlev_min_def:6, + reserved_rxlev_min_def:2; + uint8_t ho_margin_def:5, + reserved_ho_margin_def:3; + uint8_t ms_txpwr_max_def:5, + reserved_ms_txpwr_max_def:3; +}__attribute__ ((packed)); + +struct ipac_preproc_cfg { + uint8_t meas_rep_mode; + uint32_t meas_mode_flags; + struct ipac_preproc_ave_cfg ms_ave_cfg[3]; + struct ipac_preproc_ave_cfg ave_cfg; + struct ipac_preproc_ho_thresh ho_thresh; + struct ipac_preproc_ho_comp ho_comp; + struct ipac_preproc_ncell_dflts ncell_dflts; }; /*! @} */ diff --git a/src/gsm/rsl.c b/src/gsm/rsl.c index 910e848..b46c9f2 100644 --- a/src/gsm/rsl.c +++ b/src/gsm/rsl.c @@ -538,6 +538,11 @@ [RSL_IPAC_EIE_NCELL_LIST_EXT] = { TLV_TYPE_TLV }, [RSL_IPAC_EIE_MASTER_KEY] = { TLV_TYPE_TLV }, [RSL_IPAC_EIE_MASTER_SALT] = { TLV_TYPE_TLV }, + [RSL_IPAC_EIE_MEAS_TRANS_RES] = {TLV_TYPE_TV}, + [RSL_IPAC_EIE_3G_HO_PARAM] = { TLV_TYPE_TLV }, + [RSL_IPAC_EIE_3G_NCELL_LIST] = { TLV_TYPE_TLV }, + [RSL_IPAC_EIE_SDCCH_CTL_PARAM] = { TLV_TYPE_TV }, + [RSL_IPAC_EIE_AMR_CONV_THRESH] = { TLV_TYPE_FIXED, 9 }, }, }; -- To view, visit https://gerrit.osmocom.org/812 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:08:52 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:08:52 +0000 Subject: [PATCH] openbsc[master]: Introduce IPAC manufacture-defined measurement pre-processin... Message-ID: Review at https://gerrit.osmocom.org/813 Introduce IPAC manufacture-defined measurement pre-processing variables Change-Id: I95029aa2480216307bae3c5ce324f84a6f17bb3a --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 61 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/13/813/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index ce2e9b7..d2170dc 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -126,8 +126,14 @@ /* BTS ONLY */ #define MAX_NUM_UL_MEAS 104 +#define MAX_NUM_MEAS_PREPROC 32 #define LC_UL_M_F_L1_VALID (1 << 0) #define LC_UL_M_F_RES_VALID (1 << 1) +#define LC_NCELL_M_F_BA1 (1 << 2) +#define LC_UL_M_F_DTX (1 << 3) +#define LC_DL_M_F_RES_VALID (1 << 4) +#define LC_AVE_F_RES_VALID (1 << 5) +#define LC_AVE_F_CACHE_VALID (1 << 6) struct bts_ul_meas { /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */ @@ -293,6 +299,58 @@ struct gsm_meas_rep_unidir ul_res; } meas; struct { + /* UL measurement result */ + struct gsm_meas_rep_unidir ul_res; + /* DL measurement result */ + struct gsm_meas_rep_unidir dl_res; + /* UL RxLev measurement cache*/ + uint8_t ul_ave_vec[MAX_NUM_MEAS_PREPROC]; + /* UL RxLev measurement averaged buffer */ + uint8_t ul_ave_res[MAX_NUM_MEAS_PREPROC]; + /* DL RxLev measurement cache*/ + uint8_t dl_ave_vec[MAX_NUM_MEAS_PREPROC]; + /* DL RxLev measurement averaged buffer */ + uint8_t dl_ave_res[MAX_NUM_MEAS_PREPROC]; + /* UL RxQual measurement cache*/ + uint8_t ul_qual_ave_vec[MAX_NUM_MEAS_PREPROC]; + /* UL RxQual measurement averaged buffer */ + uint8_t ul_qual_ave_res[MAX_NUM_MEAS_PREPROC]; + /* DL RxQual measurement cache*/ + uint8_t dl_qual_ave_vec[MAX_NUM_MEAS_PREPROC]; + /* DL RxQual measurement averaged buffer */ + uint8_t dl_qual_ave_res[MAX_NUM_MEAS_PREPROC]; + /* MS-BTS distance measurement cache*/ + uint8_t ms_bts_ave_vec[MAX_NUM_MEAS_PREPROC]; + /* MS-BTS distance averaged buffer*/ + uint8_t ms_bts_ave_res[MAX_NUM_MEAS_PREPROC]; + /* MS power in dBm */ + int8_t ms_pwr; + /* MS timing advance */ + uint8_t ms_ta; + /* neighbor measurement reports for up to 6 cells */ + uint8_t num_cell; + /* current HO cause flags */ + uint32_t cur_ho_causes; + /* recorded HO cause flags */ + uint32_t rec_ho_causes; + /* neighbor cell measurement */ + struct { + uint8_t rxlev; + uint8_t rxlev_vec[MAX_NUM_MEAS_PREPROC]; + uint8_t rxlev_ave_res[MAX_NUM_MEAS_PREPROC]; + uint8_t bsic; + uint8_t bcch_freq; + } cell[6]; + /* measurement result index */ + uint8_t meas_idx; + /* measurement averaging index */ + uint8_t meas_ave_idx; + /* better candidate cell index */ + uint8_t better_ncell; + /* measurement preprocessing HO timer */ + struct osmo_timer_list preproc_ho_timer; + } meas_preproc; + struct { struct amr_multirate_conf amr_mr; struct { uint8_t buf[16]; @@ -434,6 +492,9 @@ } ipaccess; }; struct gsm_bts_trx_ts ts[TRX_NR_TS]; + + /*measurement preprocessing parameters */ + struct ipac_preproc_cfg trx_preproc_cfg; }; #define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) -- To view, visit https://gerrit.osmocom.org/813 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I95029aa2480216307bae3c5ce324f84a6f17bb3a Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Fri Sep 2 18:45:49 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Fri, 2 Sep 2016 18:45:49 +0000 Subject: [PATCH] osmo-bts[master]: sysmo: Fix build error for sysmobts target Message-ID: Review at https://gerrit.osmocom.org/814 sysmo: Fix build error for sysmobts target Change-Id: I29e9bf8db483376cdf5084658a738f1589622e53 --- M src/common/oml.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/14/814/1 diff --git a/src/common/oml.c b/src/common/oml.c index 29cba5a..06d0ba0 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -45,8 +45,9 @@ #include #ifdef ENABLE_LC15BTS #include "../osmo-bts-litecell15/lc15bts.h" -struct oml_fail_evt_rep_sig_data alarm_sig_data; #endif + +struct oml_fail_evt_rep_sig_data alarm_sig_data; /* FIXME: move this to libosmocore */ static struct tlv_definition abis_nm_att_tlvdef_ipa = { @@ -1732,6 +1733,7 @@ sig_data->add_text); break; +#ifdef ENABLE_LC15BTS case S_NM_OML_BTS_DSP_ALIVE_ALARM: memcpy(&res, sig_data->spare, sizeof(unsigned int)); snprintf(log_msg, 100, "Timeout waiting for SYS primitive %s (%d)\n", @@ -1745,6 +1747,7 @@ NM_EVT_CAUSE_CRIT_DSP_FATAL, sig_data->add_text); break; +#endif case S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM: memcpy(&res, sig_data->spare, sizeof(unsigned int)); -- To view, visit https://gerrit.osmocom.org/814 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I29e9bf8db483376cdf5084658a738f1589622e53 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Sat Sep 3 19:48:14 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 3 Sep 2016 19:48:14 +0000 Subject: osmo-bts[master]: LC15: fix coding style In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/807/1/src/osmo-bts-litecell15/calib_file.c File src/osmo-bts-litecell15/calib_file.c: Line 309: int i, rc, sz; I can't spot where this 'int i' is coming from, could you point me at it? -- To view, visit https://gerrit.osmocom.org/807 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18d07822df1f36a6855b72f83e2d73d221aa8735 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 11:19:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 11:19:27 +0000 Subject: osmo-bts[master]: LC15: Implementation of LC15 specific features In-Reply-To: References: Message-ID: Patch Set 1: Please name the actual features in the commit log message. -- To view, visit https://gerrit.osmocom.org/808 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I79416faaa3ba328c9c2dabcd695a1b880fe666da Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 11:22:35 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 11:22:35 +0000 Subject: osmo-bts[master]: sysmo: Fix build error for sysmobts target In-Reply-To: References: Message-ID: Patch Set 1: Apparently this fixes a bug introduced in patch #809. Would be nice to merge this patch into #809, so that it is correct to begin with. https://gerrit.osmocom.org/809 -- To view, visit https://gerrit.osmocom.org/814 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29e9bf8db483376cdf5084658a738f1589622e53 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 11:34:30 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 11:34:30 +0000 Subject: libosmocore[master]: IPAC manufacture-defined measurement pre-processing definitions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (5 comments) looks ok in general, but fix minor issues please https://gerrit.osmocom.org/#/c/812/1/include/osmocom/gsm/protocol/gsm_08_58.h File include/osmocom/gsm/protocol/gsm_08_58.h: Line 175: RSL_MT_IPAC_HO_CAN_RES = 0x62, whitespace: 1x missing space '/* Exten...' 3x space-before-tab typo: 'Extended' Line 303: IPAC_UNWEIGHTED_AVE = 0, All other names in this file start with RSL_. I guess yours should thus be 'RSL_IPAC_*' or 'RSL_IE_IPAC_*'. Line 335: }; add a blank line Line 653: struct ipac_preproc_ave_cfg { These structs will need a big-endian compat shim, see for example: http://git.osmocom.org/libosmocore/plain/include/osmocom/gsm/protocol/gsm_03_41.h struct gsm341_ms_message { struct { #if OSMO_IS_LITTLE_ENDIAN == 1 uint8_t code_hi:6; uint8_t gs:2; uint8_t update:4; uint8_t code_lo:4; #else uint8_t gs:2; uint8_t code_hi:6; uint8_t code_lo:4; uint8_t update:4; #endif (reverse the order within each 8-bit "frame") https://gerrit.osmocom.org/#/c/812/1/src/gsm/rsl.c File src/gsm/rsl.c: Line 545: [RSL_IPAC_EIE_AMR_CONV_THRESH] = { TLV_TYPE_FIXED, 9 }, space before tab -- To view, visit https://gerrit.osmocom.org/812 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:19:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 12:19:03 +0000 Subject: [PATCH] libosmo-abis[master]: osmo_ortp.c: fix order of set_connected_mode and set_remote_... Message-ID: Review at https://gerrit.osmocom.org/815 osmo_ortp.c: fix order of set_connected_mode and set_remote_addr In libortp, rtp_session_set_connected_mode() sets a flag that is used in rtp_session_set_remote_addr(). The name rtp_session_set_remote_addr() is misleading: this function actually does take a lot of action, including an attempt to connect to the remote server. Thus the "connected mode" flag needs to be set before this. Suggested-by: NuRan Wireless Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e --- M src/trau/osmo_ortp.c 1 file changed, 6 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/15/815/1 diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index eb78212..cdcc1e7 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -392,16 +392,18 @@ return 0; } - rc = rtp_session_set_remote_addr(rs->sess, ip, port); - if (rc < 0) - return rc; - /* enable the use of connect() so later getsockname() will * actually return the IP address that was chosen for the local * sid of the connection */ rtp_session_set_connected_mode(rs->sess, 1); rs->flags &= ~OSMO_RTP_F_DISABLED; + /* This call attempts to connect to the remote address, so make sure to + * set all other rtp session configuration before this call. */ + rc = rtp_session_set_remote_addr(rs->sess, ip, port); + if (rc < 0) + return rc; + if (rs->flags & OSMO_RTP_F_POLL) return rc; else -- To view, visit https://gerrit.osmocom.org/815 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:23 +0000 Subject: openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Patch Set 9: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:34 +0000 Subject: [MERGED] openbsc[master]: IuPS: dev hack: init hardcoded Ki on ATT REQ In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: dev hack: init hardcoded Ki on ATT REQ ...................................................................... IuPS: dev hack: init hardcoded Ki on ATT REQ DEVELOPMENT HACK: Our current HLR does not support 3G authentication tokens. A new HLR/VLR implementation is being developed. Until it is ready and actual milenage authentication is properly supported, we are hardcoding a fixed Ki and use 2G auth. Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8b8bdd1..7d00bd5 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1039,6 +1040,34 @@ ctx->ra = ra_id; if (ctx->ran_type == MM_CTX_T_GERAN_Gb) ctx->gb.cell_id = cid; + else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) { + /* DEVELOPMENT HACK: Our current HLR does not support 3G + * authentication tokens. A new HLR/VLR implementation is being + * developed. Until it is ready and actual milenage + * authentication is properly supported, we are hardcoding a + * fixed Ki and use 2G auth. */ + unsigned char tmp_rand[16]; + /* Ki 000102030405060708090a0b0c0d0e0f */ + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1, + .u.gsm.ki = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + }; + /* XXX: Hack to make 3G auth work with special SIM card */ + ctx->auth_state = SGSN_AUTH_AUTHENTICATE; + + RAND_bytes(tmp_rand, 16); + + memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec)); + osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand); + + ctx->auth_triplet.key_seq = 0; + } + /* Update MM Context with other data */ ctx->drx_parms = drx_par; ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; -- To view, visit https://gerrit.osmocom.org/734 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ieca45960fa941a3a706c6e479b04b9f2ef89d860 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:34 +0000 Subject: [MERGED] openbsc[master]: IuPS: send Security Mode Command, track the new_key flag. In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: send Security Mode Command, track the new_key flag. ...................................................................... IuPS: send Security Mode Command, track the new_key flag. Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 2 files changed, 14 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 7d00bd5..14043ce 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -612,6 +612,9 @@ ctx->is_authenticated = 1; + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + ctx->iu.new_key = 1; + /* FIXME: enable LLC cipheirng */ /* Check if we can let the mobile station enter */ @@ -690,6 +693,9 @@ /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { +#ifdef BUILD_IU + int rc; +#endif #ifndef PTMSI_ALLOC struct sgsn_signal_data sig_data; #endif @@ -743,6 +749,13 @@ } /* The MS is authorized */ +#ifdef BUILD_IU + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) { + rc = iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet, 0, ctx->iu.new_key); + ctx->iu.new_key = 0; + return rc; + } +#endif switch (ctx->pending_req) { case 0: diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 19b0a1b..dd7e008 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -244,6 +244,7 @@ ctx->ran_type = MM_CTX_T_UTRAN_Iu; ctx->iu.ue_ctx = uectx; + ctx->iu.new_key = 1; ctx->mm_state = GMM_DEREGISTERED; ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0); -- To view, visit https://gerrit.osmocom.org/735 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0b2593c2df13b79eb36975b0d302e31cfdf8bb09 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:34 +0000 Subject: [MERGED] openbsc[master]: IuPS: Introduce function to change PMM state In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: Introduce function to change PMM state ...................................................................... IuPS: Introduce function to change PMM state This is where IuPS will redirect GTP-U endpoints in a subsequent commit. Also add comprehensive logging of pmm_state transitions. Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 29 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index c17d813..cb3d4ee 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,29 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) +{ + if (ctx->pmm_state == state) + return; + + LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %i to %i\n", ctx->pmm_state, state); + + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) + { + switch (state) { + case PMM_IDLE: + /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + break; + case PMM_CONNECTED: + break; + default: + break; + } + } + + ctx->pmm_state = state; +} + #ifdef BUILD_IU int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data) @@ -132,7 +155,7 @@ /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); if (mm->pmm_state == PMM_CONNECTED) - mm->pmm_state = PMM_IDLE; + mmctx_set_pmm_state(mm, PMM_IDLE); rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -243,7 +266,8 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; - ctx->pmm_state = PMM_DETACHED; + + mmctx_set_pmm_state(ctx, PMM_DETACHED); sgsn_mm_ctx_cleanup_free(ctx); } @@ -854,9 +878,8 @@ return gsm48_tx_gmm_att_ack(ctx); #ifdef BUILD_IU case GSM48_MT_GMM_SERVICE_REQ: - /* TODO: PMM State transition */ ctx->pending_req = 0; - ctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(ctx, PMM_CONNECTED); rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1798,7 +1821,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1821,7 +1844,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; - mmctx->pmm_state = PMM_CONNECTED; + mmctx_set_pmm_state(mmctx, PMM_CONNECTED); rc = 0; memset(&sig_data, 0, sizeof(sig_data)); -- To view, visit https://gerrit.osmocom.org/741 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7c2cd1abc1805659b01dffffff31c49fe5161086 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:35 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:35 +0000 Subject: [MERGED] openbsc[master]: IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE when data arrives ...................................................................... IuPS: Change GTP-U endpoint to SGSN in PMM_IDLE and page UE when data arrives Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b --- M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 3 files changed, 32 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..22809b7 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -138,6 +138,7 @@ uint16_t nsapi, struct tlv_parsed *tp); int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); /* gprs_sndcp.c */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index cb3d4ee..3d74647 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -109,6 +109,16 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); +static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx) +{ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) { + sgsn_pdp_upd_gtp_u(pdp, + &sgsn->cfg.gtp_listenaddr.sin_addr, + sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); + } +} + void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) { if (ctx->pmm_state == state) @@ -120,7 +130,8 @@ { switch (state) { case PMM_IDLE: - /* TODO: Change GTP-U endpoints to SGSN, start RA Upd timer */ + /* TODO: start RA Upd timer */ + mmctx_change_gtpu_endpoints_to_sgsn(ctx); break; case PMM_CONNECTED: break; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 35d5dab..04bd40a 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -401,6 +401,13 @@ return EOF; } +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen) +{ + pdp->lib->gsnlu.l = alen; + memcpy(pdp->lib->gsnlu.v, addr, alen); + gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); +} + #ifdef BUILD_IU /* Callback for RAB assignment response */ int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) @@ -621,6 +628,18 @@ return -EIO; } + if (mm->ran_type == MM_CTX_T_UTRAN_Iu) { +#ifdef BUILD_IU + /* Ignore the packet for now and page the UE to get the RAB + * reestablished */ + iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac, mm->ra.rac); + + return 0; +#else + return -ENOTSUP; +#endif + } + msg = msgb_alloc_headroom(len+256, 128, "GTP->SNDCP"); ud = msgb_put(msg, len); memcpy(ud, packet, len); -- To view, visit https://gerrit.osmocom.org/742 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I47b73a40cbdda6b7c31fb2767f74f9f93d84056b Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:36 +0000 Subject: [MERGED] openbsc[master]: IuPS: GMM Attach: reset MM ctx pending_req In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: GMM Attach: reset MM ctx pending_req ...................................................................... IuPS: GMM Attach: reset MM ctx pending_req Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 99e4a8c..c17d813 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -836,6 +836,7 @@ "no pending request, authorization completed\n"); break; case GSM48_MT_GMM_ATTACH_REQ: + ctx->pending_req = 0; extract_subscr_msisdn(ctx); extract_subscr_hlr(ctx); -- To view, visit https://gerrit.osmocom.org/740 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0df0f3d88085939eb617405e2013ad164eed477b Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:36 +0000 Subject: [MERGED] openbsc[master]: IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM state ...................................................................... IuPS: sgsn_mm_ctx: add enum gprs_pmm_state field, track PMM state Iu needs to page to transfer data in PMM-IDLE state. Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 --- M openbsc/include/openbsc/gprs_sgsn.h M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/gprs_sgsn.c 3 files changed, 18 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 18cbab8..24e286c 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -31,6 +31,16 @@ 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, @@ -117,6 +127,7 @@ char imsi[GSM23003_IMSI_MAX_DIGITS+1]; enum gprs_gmm_state mm_state; + enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ uint32_t p_tmsi; uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ uint32_t p_tmsi_sig; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 53b6322..99e4a8c 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -131,6 +131,8 @@ case IU_EVENT_LINK_INVALIDATED: /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + if (mm->pmm_state == PMM_CONNECTED) + mm->pmm_state = PMM_IDLE; rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -241,6 +243,7 @@ /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; + ctx->pmm_state = PMM_DETACHED; sgsn_mm_ctx_cleanup_free(ctx); } @@ -852,6 +855,7 @@ case GSM48_MT_GMM_SERVICE_REQ: /* TODO: PMM State transition */ ctx->pending_req = 0; + ctx->pmm_state = PMM_CONNECTED; rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) @@ -1793,6 +1797,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1815,6 +1820,7 @@ mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index dd7e008..e5a54d9 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -246,6 +246,7 @@ 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); -- To view, visit https://gerrit.osmocom.org/739 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id37778cb9a0328a21c8e8246998ecdb43dd687d8 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:36 +0000 Subject: [MERGED] openbsc[master]: IuPS: RA UPD: make sure to authorize, for Iu Integrity Prote... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: RA UPD: make sure to authorize, for Iu Integrity Protection ...................................................................... IuPS: RA UPD: make sure to authorize, for Iu Integrity Protection Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 7 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index b515abd..53b6322 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -50,6 +50,7 @@ #ifdef BUILD_IU #include +#include #endif #include @@ -853,9 +854,8 @@ ctx->pending_req = 0; rc = gsm48_tx_gmm_service_ack(ctx); - if (ctx->iu.service.type == 1) { + if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) activate_pdp_rabs(ctx); - } return rc; #endif @@ -1540,8 +1540,11 @@ process_ms_ctx_status(mmctx, pdp_status); } - /* Send RA UPDATE ACCEPT */ - return gsm48_tx_gmm_ra_upd_ack(mmctx); + /* Send RA UPDATE ACCEPT. In Iu, the RA upd request can be called from + * a new Iu connection, so we might need to re-authenticate the + * connection as well as turn on integrity protection. */ + mmctx->pending_req = GSM48_MT_GMM_RA_UPD_REQ; + return gsm48_gmm_authorize(mmctx); rejected: /* Send RA UPDATE REJECT */ -- To view, visit https://gerrit.osmocom.org/738 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2ea2089895f8a8e125ef39d9bef70dafb2b1ce69 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:28:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:28:36 +0000 Subject: [MERGED] openbsc[master]: IuPS: add GMM Service Request rx and tx In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IuPS: add GMM Service Request rx and tx ...................................................................... IuPS: add GMM Service Request rx and tx Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 199 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 14043ce..b515abd 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -690,6 +690,75 @@ strncpy(&ctx->hlr[0], called.number, sizeof(ctx->hlr) - 1); } +#ifdef BUILD_IU +/* Chapter 9.4.21: Service accept */ +static int gsm48_tx_gmm_service_ack(struct sgsn_mm_ctx *mm) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE ACK"); + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_INFO, mm, "<- GPRS SERVICE ACCEPT (P-TMSI=0x%08x)\n", mm->p_tmsi); + + mmctx2msgid(msg, mm); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_ACK; + + /* Optional: PDP context status */ + /* Optional: MBMS context status */ + + return gsm48_gmm_sendmsg(msg, 0, mm, false); +} +#endif + +/* Chapter 9.4.22: Service reject */ +static int _tx_gmm_service_rej(struct msgb *msg, uint8_t gmm_cause, + const struct sgsn_mm_ctx *mm) +{ + struct gsm48_hdr *gh; + + LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS SERVICE REJECT: %s\n", + get_value_string(gsm48_gmm_cause_names, gmm_cause)); + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_SERVICE_REJ; + gh->data[0] = gmm_cause; + + return gsm48_gmm_sendmsg(msg, 0, NULL, true); +} +static int gsm48_tx_gmm_service_rej_oldmsg(const struct msgb *old_msg, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ OLD"); + gmm_copy_id(msg, old_msg); + return _tx_gmm_service_rej(msg, gmm_cause, NULL); +} +#if 0 +-- currently unused -- +static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm, + uint8_t gmm_cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ"); + mmctx2msgid(msg, mm); + return _tx_gmm_service_rej(msg, gmm_cause, mm); +} +#endif + +static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm); + +#ifdef BUILD_IU +void activate_pdp_rabs(struct sgsn_mm_ctx *ctx) +{ + /* Send RAB activation requests for all PDP contexts */ + struct sgsn_pdp_ctx *pdp; + llist_for_each_entry(pdp, &ctx->pdp_list, list) { + iu_rab_act_ps(pdp->nsapi, pdp, 1); + } +} +#endif + /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { @@ -778,6 +847,23 @@ #endif return gsm48_tx_gmm_att_ack(ctx); +#ifdef BUILD_IU + case GSM48_MT_GMM_SERVICE_REQ: + /* TODO: PMM State transition */ + ctx->pending_req = 0; + rc = gsm48_tx_gmm_service_ack(ctx); + + if (ctx->iu.service.type == 1) { + activate_pdp_rabs(ctx); + } + + return rc; +#endif + case GSM48_MT_GMM_RA_UPD_REQ: + ctx->pending_req = 0; + /* Send RA UPDATE ACCEPT */ + return gsm48_tx_gmm_ra_upd_ack(ctx); + default: LOGMMCTXP(LOGL_ERROR, ctx, "only Attach Request is supported yet, " @@ -1473,6 +1559,116 @@ return rc; } +/* 3GPP TS 24.008 Section 9.4.20 Service request. + * In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back + * to PMM-CONNECTED mode. */ +static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) +{ + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); + uint8_t *cur = gh->data, *mi; + uint8_t ciph_seq_nr, service_type, mi_len, mi_type; + uint32_t tmsi; + struct tlv_parsed tp; + char mi_string[GSM48_MI_SIZE]; + enum gsm48_gmm_cause reject_cause; + int rc; + + LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST "); + + /* This message is only valid in Iu mode */ + if (!msg->dst) { + LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n"); + return -1; + } + + /* Skip Ciphering key sequence number 10.5.1.2 */ + ciph_seq_nr = *cur & 0x07; + + /* Service type 10.5.5.20 */ + service_type = (*cur++ >> 4) & 0x07; + + /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ + mi_len = *cur++; + mi = cur; + if (mi_len > 8) + goto err_inval; + mi_type = *mi & GSM_MI_TYPE_MASK; + cur += mi_len; + + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + + DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string, + get_value_string(gprs_service_t_strs, service_type)); + + LOGPC(DMM, LOGL_INFO, "\n"); + + /* Optional: PDP context status, MBMS context status, Uplink data status, Device properties */ + tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, (msg->data + msg->len) - cur, 0, 0); + + switch (mi_type) { + case GSM_MI_TYPE_IMSI: + /* Try to find MM context based on IMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_imsi(mi_string); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + case GSM_MI_TYPE_TMSI: + memcpy(&tmsi, mi+1, 4); + tmsi = ntohl(tmsi); + /* Try to find MM context based on P-TMSI */ + if (!ctx) + ctx = sgsn_mm_ctx_by_ptmsi(tmsi); + if (!ctx) { + /* FIXME: We need to have a context for service request? */ + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } + msgid2mmctx(ctx, msg); + break; + default: + LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting SERVICE REQUEST with " + "MI type %s\n", gsm48_mi_type_name(mi_type)); + reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; + goto rejected; + } + + ctx->mm_state = GMM_COMMON_PROC_INIT; + + ctx->iu.service.type = service_type; + + /* TODO: Handle those only in case of accept? */ + /* Look at PDP Context Status IE and see if MS's view of + * activated/deactivated NSAPIs agrees with our view */ + if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) { + const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS); + process_ms_ctx_status(ctx, pdp_status); + } + + + ctx->pending_req = GSM48_MT_GMM_SERVICE_REQ; + return gsm48_gmm_authorize(ctx); + +err_inval: + LOGPC(DMM, LOGL_INFO, "\n"); + reject_cause = GMM_CAUSE_SEM_INCORR_MSG; + +rejected: + /* Send SERVICE REJECT */ + LOGMMCTXP(LOGL_NOTICE, ctx, + "Rejecting Service Request with cause '%s' (%d)\n", + get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); + rc = gsm48_tx_gmm_service_rej_oldmsg(msg, reject_cause); + + return rc; + +} + + static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); @@ -1551,6 +1747,9 @@ case GSM48_MT_GMM_ATTACH_REQ: rc = gsm48_rx_gmm_att_req(mmctx, msg, llme); break; + case GSM48_MT_GMM_SERVICE_REQ: + rc = gsm48_rx_gmm_service_req(mmctx, msg); + break; /* For all the following types mmctx can not be NULL */ case GSM48_MT_GMM_ID_RESP: if (!mmctx) -- To view, visit https://gerrit.osmocom.org/737 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib935de22d23a15f449927840d4d59497ce22abbd Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:29:05 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:29:05 +0000 Subject: libosmo-abis[master]: osmo_ortp.c: fix order of set_connected_mode and set_remote_... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/815 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:33:45 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:33:45 +0000 Subject: osmo-bts[master]: LC15: Implementation of LC15 specific features In-Reply-To: References: Message-ID: Patch Set 1: (4 comments) https://gerrit.osmocom.org/#/c/808/1/include/osmo-bts/gsm_data.h File include/osmo-bts/gsm_data.h: Line 115: /* specific to LC15 BTS */ we don't generally have bts-model specific state here for other BTSs. So if there's a more elegant method, let's explore that. I guess it is not possible to attach the state to the phy_link or phy_interface, as you have two phy_links and only one LED state control? https://gerrit.osmocom.org/#/c/808/1/src/osmo-bts-litecell15/l1_if.c File src/osmo-bts-litecell15/l1_if.c: Line 1243: if(btsb->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS) if is not a function call, hence we use space after 'if'. Line 1563: struct msgb *msg = sysp_msgb_alloc(); we typically declare all variables on top of the function. Sae below with 'int rc' and 'Litecell15_Prim_t'. https://gerrit.osmocom.org/#/c/808/1/src/osmo-bts-litecell15/lc15bts.h File src/osmo-bts-litecell15/lc15bts.h: Line 25: enum lc15_diversity_mode{ would be great to have a space here, like in the rest of the code. -- To view, visit https://gerrit.osmocom.org/808 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I79416faaa3ba328c9c2dabcd695a1b880fe666da Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 12:37:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 12:37:46 +0000 Subject: osmo-bts[master]: LC15: Implementation of major BTS alarms In-Reply-To: References: Message-ID: Patch Set 1: (4 comments) https://gerrit.osmocom.org/#/c/809/1/include/osmo-bts/oml.h File include/osmo-bts/oml.h: Line 50: NM_EVT_CAUSE_CRIT_SW_FATAL = 0x3000, who defined those cause value? are they from TS 12.21? If yes, the definitions should definitely go into libosmgsm abis_nm.h. If the'yre custom definitions, we need to mention it clearly here, and if possible also introduce a OSMO in the definition to make it explicit those cause values are not standard cause values. Like NM_EVT_CAUSE_OMSO_... https://gerrit.osmocom.org/#/c/809/1/src/common/bts.c File src/common/bts.c: Line 180: INIT_LLIST_HEAD(&btsb->lc15.ceased_alarm_list); is the 'ceased alarm' mechanism really Litecell 1.5 specific, or is it a more general feature that is shared among all BTS models? https://gerrit.osmocom.org/#/c/809/1/src/common/rsl.c File src/common/rsl.c: Line 397: /* Send Failure event report of BTS page table is full to BSC */ we typically don't indent the 'case' below a 'switch' https://gerrit.osmocom.org/#/c/809/1/src/osmo-bts-litecell15/calib_file.c File src/osmo-bts-litecell15/calib_file.c: Line 156: if( fl1h->phy_inst->trx ){ space missing, also in several other places. -- To view, visit https://gerrit.osmocom.org/809 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic4e088a3af115d3d5a124b61c1e92eed277d3469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:14:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 13:14:18 +0000 Subject: [PATCH] osmo-bts[master]: dyn TS: if PCU is not connected, allow operation as TCH In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/748 to look at the new patch set (#4). dyn TS: if PCU is not connected, allow operation as TCH Before this patch, Osmocom style TCH/F_TCH/H_PDCH dyn TS were paralyzed if no PCU was running. The state of the dyn TS would lock up in the PDCH activation phase since the PCU never completed the process. Make more robust, i.e. don't concern the BSC with PDCH activation failures. This matches the way plain PDCH TS work: besides declaring the TS as PDCH, the BSC is not involved and is not told about errors. During PDCH deactivation, still wait for the PCU to tear down the PDTCH SAPIs, but in case no PCU is connected, send a rel ack right away. Thus, the BSC will happily switch Osmocom style dynamic timeslots to and from PDCH mode, using the dyn TS as voice channels as needed, and not caring about possible PDCH failures. GPRS starts working right away as soon as a PCU connects, regardless of dyn TS having been used for voice any number of times, and without another switchover needed. In detail: In rsl_rx_chan_activ(), upon receiving a PDCH activation, send an RSL chan act ack right away, unconditionally (with an explaining comment). Do not concern the Abis link with PDCH activation failures. Since we're acking right away now, drop the chan act ack that would follow after the PCU activation: as before dyn TS, only send acks and nacks for rel_act_kind == LCHAN_REL_ACT_RSL (PDCH runs as LCHAN_REL_ACT_PCU). In dyn_ts_pdch_release, indicate that the PCU is not connected by means of returning 1. In rsl_rx_rf_chan_rel(), use this indicator to send a rel ack right away if the PCU is not connected. Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 --- M src/common/rsl.c 1 file changed, 34 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/48/748/4 diff --git a/src/common/rsl.c b/src/common/rsl.c index 8905028..559599f 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -606,14 +606,7 @@ /* Send an RSL Channel Activation Ack if cause is zero, a Nack otherwise. */ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause) { - /* - * Normally, PDCH activation via PCU does not ack back to the BSC. - * But for GSM_PCHAN_TCH_F_TCH_H_PDCH, send a non-standard act ack for - * LCHAN_REL_ACT_PCU, since the act req came from RSL initially. - */ - if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL - && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH - && lchan->rel_act_kind == LCHAN_REL_ACT_PCU)) { + if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) { LOGP(DRSL, LOGL_NOTICE, "%s not sending CHAN ACT %s\n", gsm_lchan_name(lchan), cause ? "NACK" : "ACK"); return 0; @@ -931,6 +924,29 @@ if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH && ts->dyn.pchan_want == GSM_PCHAN_PDCH) { /* + * We ack the activation to the BSC right away, regardless of + * the PCU succeeding or not; if a dynamic timeslot fails to go + * to PDCH mode for any reason, the BSC should still be able to + * switch it back to TCH modes and should not put the time slot + * in an error state. So for operating dynamic TS, the BSC + * would not take any action if the PDCH mode failed, e.g. + * because the PCU is not yet running. Even if alerting the + * core network of broken GPRS service is desired, this only + * makes sense when the PCU has not shown up for some time. + * It's easiest to not forward activation delays to the BSC: if + * the BSC tells us to do PDCH, we do our best, and keep the + * details on the BTS and PCU level. This is kind of analogous + * to how plain PDCH TS operate. Directly call + * rsl_tx_chan_act_ack() instead of rsl_tx_chan_act_acknack() + * because we don't want/need to decide whether to drop due to + * lchan->rel_act_kind. + */ + rc = rsl_tx_chan_act_ack(lchan); + if (rc < 0) + LOGP(DRSL, LOGL_ERROR, "%s Cannot send act ack: %d\n", + gsm_ts_and_pchan_name(ts), rc); + + /* * pcu_tx_info_ind() will pick up the ts->dyn.pchan_want. If * the PCU is not connected yet, ignore for now; the PCU will * catch up (and send the RSL ack) once it connects. @@ -981,7 +997,7 @@ /* PCU not connected yet. Just record the new type and done, * the PCU will pick it up once connected. */ ts->dyn.pchan_is = GSM_PCHAN_NONE; - return 0; + return 1; } return pcu_tx_info_ind(); @@ -990,6 +1006,8 @@ /* 8.4.14 RF CHANnel RELease is received */ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) { + int rc; + if (lchan->abis_ip.rtp_socket) { rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); @@ -1004,8 +1022,13 @@ /* Dynamic channel in PDCH mode is released via PCU */ if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH - && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) - return dyn_ts_pdch_release(lchan); + && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { + rc = dyn_ts_pdch_release(lchan); + if (rc != 1) + return rc; + /* If the PCU is not connected, continue right away. */ + return rsl_tx_rf_rel_ack(lchan); + } l1sap_chan_rel(lchan->ts->trx, chan_nr); -- To view, visit https://gerrit.osmocom.org/748 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:27:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:27:36 +0000 Subject: osmo-bts[master]: LC15: Allow BTS to forward PCU failure alarms to network In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/810/1/include/osmo-bts/pcuif_proto.h File include/osmo-bts/pcuif_proto.h: PS1, Line 144: r severity, there's an extra 'r' -- To view, visit https://gerrit.osmocom.org/810 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I39bb8f8b749e94394909aa4a4be000c306ed712a Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:32:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:32:02 +0000 Subject: osmo-bts[master]: LC15: Implementation of TS 12.21 measurement related message... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (4 comments) https://gerrit.osmocom.org/#/c/811/1//COMMIT_MSG Commit Message: Line 7: LC15: Implementation of TS 12.21 measurement related messages to measure PCU KPI the commit message should contain much more details on this. First of all, it seems that the specific measurement related messages are not part of TS 12.21, but rather related to the IPA dialect of OML. Secondly, please give a short summary of the measurement message types and how they are used. https://gerrit.osmocom.org/#/c/811/1/include/osmo-bts/oml.h File include/osmo-bts/oml.h: Line 61: enum abis_nm_ipacc_meas_type { if this is a definition about parts of the IPA-stype abis/ip, the related definitions belong into libosmogsm, from where they can be shared by both BTS and BSC (or other code). https://gerrit.osmocom.org/#/c/811/1/src/common/oml.c File src/common/oml.c: Line 98: [NM_ATT_MEAS_TYPE] = { TLV_TYPE_TV }, when adding new definitions to an existing table or enum, pleas always use the same indenting as the existing elements. Line 1214: LOGP(DOML, LOGL_NOTICE, "%s Unsupported NM STOP MEASurement type received 0x%02x\n", gsm_abis_mo_name(mo), meas_id); please respect the 80-char-long-line limit of the kernel coding style that we use in osmocom. -- To view, visit https://gerrit.osmocom.org/811 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I352600f964e6c161b9259c62f2e0a0f39f0f60d9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:32:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:32:54 +0000 Subject: openbsc[master]: Introduce IPAC manufacture-defined measurement pre-processin... In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/813/1/openbsc/include/openbsc/gsm_data_shared.h File openbsc/include/openbsc/gsm_data_shared.h: Line 496: /*measurement preprocessing parameters */ space -- To view, visit https://gerrit.osmocom.org/813 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95029aa2480216307bae3c5ce324f84a6f17bb3a Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:33:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:33:39 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:33:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:33:49 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:35:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:35:28 +0000 Subject: openbsc[master]: bts: extend bts_chan_load to allow counting tch only In-Reply-To: References: Message-ID: Patch Set 1: seems fine to me, but it would be good to indicate in the commit message why that is done :) -- To view, visit https://gerrit.osmocom.org/793 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I86f1d502649747b6b9aefcb39081b14110e8f494 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:36:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:36:01 +0000 Subject: [MERGED] openbsc[master]: gprs/gprs_llc: fix null pointer deref in gprs_llc_rcvmsg In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gprs/gprs_llc: fix null pointer deref in gprs_llc_rcvmsg ...................................................................... gprs/gprs_llc: fix null pointer deref in gprs_llc_rcvmsg Change-Id: I1f7e1d524042134c93a4f3de599c54d442447512 --- M openbsc/src/gprs/gprs_llc.c 1 file changed, 1 insertion(+), 2 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 32920da..a2ffa51 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -859,8 +859,7 @@ case GPRS_SAPI_SNDCP9: case GPRS_SAPI_SNDCP11: /* Ask an upper layer for help. */ - return gsm0408_gprs_force_reattach_oldmsg(msg, - lle->llme); + return gsm0408_gprs_force_reattach_oldmsg(msg, NULL); default: break; } -- To view, visit https://gerrit.osmocom.org/801 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1f7e1d524042134c93a4f3de599c54d442447512 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:36:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:36:01 +0000 Subject: [MERGED] openbsc[master]: gprs/gsm0408_gprs_force_reattach_oldmsg: check llme before use In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gprs/gsm0408_gprs_force_reattach_oldmsg: check llme before use ...................................................................... gprs/gsm0408_gprs_force_reattach_oldmsg: check llme before use Change-Id: I9385655872c4dcf46aa1d18bcc47b84aba2f34f7 --- M openbsc/src/gprs/gprs_gmm.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 3d74647..8de3bf7 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -2554,7 +2554,8 @@ struct gprs_llc_llme *llme) { int rc; - gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme); + if (llme) + gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme); rc = gsm48_tx_gmm_detach_req_oldmsg( msg, GPRS_DET_T_MT_REATT_REQ, GMM_CAUSE_IMPL_DETACHED); -- To view, visit https://gerrit.osmocom.org/800 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9385655872c4dcf46aa1d18bcc47b84aba2f34f7 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:36:32 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:36:32 +0000 Subject: libosmocore[master]: core/counter: add osmo_counter_dec() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/796 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I030140a45afa295c3ebc4d3ccaffd437b984f515 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:36:35 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:36:35 +0000 Subject: [MERGED] libosmocore[master]: core/counter: add osmo_counter_dec() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: core/counter: add osmo_counter_dec() ...................................................................... core/counter: add osmo_counter_dec() Change-Id: I030140a45afa295c3ebc4d3ccaffd437b984f515 --- M include/osmocom/core/statistics.h 1 file changed, 6 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/statistics.h b/include/osmocom/core/statistics.h index 1e472ff..41716cc 100644 --- a/include/osmocom/core/statistics.h +++ b/include/osmocom/core/statistics.h @@ -12,6 +12,12 @@ unsigned long previous; /*!< \brief previous value */ }; +/*! \brief Decrement counter */ +static inline void osmo_counter_dec(struct osmo_counter *ctr) +{ + ctr->value--; +} + /*! \brief Increment counter */ static inline void osmo_counter_inc(struct osmo_counter *ctr) { -- To view, visit https://gerrit.osmocom.org/796 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I030140a45afa295c3ebc4d3ccaffd437b984f515 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:37:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:37:23 +0000 Subject: osmo-pcu[master]: tbf: add llc_queue_size() to check llc_queue is valid before... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/724 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88cc3180f8f86785e3f07981895dabddf50b60a2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:37:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:37:28 +0000 Subject: osmo-pcu[master]: tbf: add llc_queue_size() to check llc_queue is valid before... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/724 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88cc3180f8f86785e3f07981895dabddf50b60a2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 13:38:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 5 Sep 2016 13:38:13 +0000 Subject: osmo-pcu[master]: llc: remove NULL-pointer check of gprs_llc_queue::size()/oct... In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/213 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I918a094e0dc59098a9eb00d152c9ae42d36b3a99 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 5 14:18:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 14:18:02 +0000 Subject: [MERGED] libosmo-abis[master]: osmo_ortp.c: fix order of set_connected_mode and set_remote_... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: osmo_ortp.c: fix order of set_connected_mode and set_remote_addr ...................................................................... osmo_ortp.c: fix order of set_connected_mode and set_remote_addr In libortp, rtp_session_set_connected_mode() sets a flag that is used in rtp_session_set_remote_addr(). The name rtp_session_set_remote_addr() is misleading: this function actually does take a lot of action, including an attempt to connect to the remote server. Thus the "connected mode" flag needs to be set before this. Suggested-by: NuRan Wireless Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e --- M src/trau/osmo_ortp.c 1 file changed, 6 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index eb78212..cdcc1e7 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -392,16 +392,18 @@ return 0; } - rc = rtp_session_set_remote_addr(rs->sess, ip, port); - if (rc < 0) - return rc; - /* enable the use of connect() so later getsockname() will * actually return the IP address that was chosen for the local * sid of the connection */ rtp_session_set_connected_mode(rs->sess, 1); rs->flags &= ~OSMO_RTP_F_DISABLED; + /* This call attempts to connect to the remote address, so make sure to + * set all other rtp session configuration before this call. */ + rc = rtp_session_set_remote_addr(rs->sess, ip, port); + if (rc < 0) + return rc; + if (rs->flags & OSMO_RTP_F_POLL) return rc; else -- To view, visit https://gerrit.osmocom.org/815 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 5 15:45:30 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 5 Sep 2016 15:45:30 +0000 Subject: libosmocore[master]: IPAC manufacture-defined measurement pre-processing definitions In-Reply-To: References: Message-ID: Patch Set 1: (3 comments) https://gerrit.osmocom.org/#/c/812/1/include/osmocom/gsm/protocol/gsm_08_58.h File include/osmocom/gsm/protocol/gsm_08_58.h: Line 304: IPAC_WEIGHTED_AVE, We usually use "avg" as abbreviation for average. Preferably use *_AVG instead of *_AVE. Line 312: IPAC_MS_BTS_DIS_AVE *_AVG Line 658: ave_method:3; As seen in the other example, we usually would write 'uint8_t' before every name. Personally, I like it the way your patch is now, because it is easy to see where the 8-bit / byte bounds are. But let's check with other reviewers whether we should stick with the other style. -- To view, visit https://gerrit.osmocom.org/812 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 5 16:15:29 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 5 Sep 2016 16:15:29 +0000 Subject: [PATCH] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS Message-ID: Review at https://gerrit.osmocom.org/816 gsm0503: migrate transcoding routines from OsmoBTS The GSM 05.03 transcoding routines are becoming increasingly popular, and some projects (such as GR-GSM and OsmocomBB) also require transcoding capabilities implemented within the libosmocore. Moreover, it would be beeter to clean up the OsmoBTS source code, sharing this code. Currently there are the following data types supported: - xCCH - PDTCH - PDTCH (EDGE) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Also, the conv_gen.py was updated, and now writes a single file. The EDGE MCS convolutional codes are migrated 'as is', i.e. already in generated state. Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a --- M .gitignore M include/osmocom/gsm/gsm0503.h A include/osmocom/gsm/gsm0503_coding.h A include/osmocom/gsm/gsm0503_interleaving.h A include/osmocom/gsm/gsm0503_mapping.h A include/osmocom/gsm/gsm0503_parity.h A include/osmocom/gsm/gsm0503_tables.h M src/gsm/Makefile.am A src/gsm/gsm0503_coding.c A src/gsm/gsm0503_conv_edge.c A src/gsm/gsm0503_interleaving.c A src/gsm/gsm0503_mapping.c A src/gsm/gsm0503_parity.c A src/gsm/gsm0503_tables.c M src/gsm/libosmogsm.map M utils/conv_gen.py 16 files changed, 6,752 insertions(+), 327 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/16/816/1 diff --git a/.gitignore b/.gitignore index 5165364..dd9c61b 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ doc/*.tag src/crc*gen.c +src/gsm/gsm6*.c src/gsm/conv*gen.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index cf1c976..3fda4ce 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -26,7 +26,7 @@ #include -/*! \file conv_gen.h +/*! \file gsm0503.h * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03 */ @@ -36,10 +36,26 @@ */ extern const struct osmo_conv_code gsm0503_xcch; +/*! \brief structure describing convolutional code RACH + */ +extern const struct osmo_conv_code gsm0503_rach; + +/*! \brief structure describing convolutional code SCH + */ +extern const struct osmo_conv_code gsm0503_sch; + /*! \brief structures describing convolutional codes CS2/3 */ extern const struct osmo_conv_code gsm0503_cs2; extern const struct osmo_conv_code gsm0503_cs3; + +/*! \brief structure describing convolutional code TCH/FR + */ +extern const struct osmo_conv_code gsm0503_tch_fr; + +/*! \brief structure describing convolutional code TCH/HR + */ +extern const struct osmo_conv_code gsm0503_tch_hr; /*! \brief structure describing convolutional code TCH/AFS 12.2 */ @@ -72,3 +88,87 @@ /*! \brief structure describing convolutional code TCH/AFS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_afs_4_75; + +/*! \brief structure describing convolutional code TCH/AHS 7.95 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_95; + +/*! \brief structure describing convolutional code TCH/AHS 7.4 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_4; + +/*! \brief structure describing convolutional code TCH/AHS 6.7 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_6_7; + +/*! \brief structure describing convolutional code TCH/AHS 5.9 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_9; + +/*! \brief structure describing convolutional code TCH/AHS 5.15 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_15; + +/*! \brief structure describing convolutional code TCH/AHS 4.75 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; + +/*! \brief structure describing convolutional code EDGE MCS1 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 + */ +extern const struct osmo_conv_code gsm0503_mcs1; + +/*! \brief structure describing convolutional code EDGE MCS2 + */ +extern const struct osmo_conv_code gsm0503_mcs2; + +/*! \brief structure describing convolutional code EDGE MCS3 + */ +extern const struct osmo_conv_code gsm0503_mcs3; + +/*! \brief structure describing convolutional code EDGE MCS4 + */ +extern const struct osmo_conv_code gsm0503_mcs4; + +/*! \brief structure describing convolutional code EDGE MCS5 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 + */ +extern const struct osmo_conv_code gsm0503_mcs5; + +/*! \brief structure describing convolutional code EDGE MCS6 + */ +extern const struct osmo_conv_code gsm0503_mcs6; + +/*! \brief structure describing convolutional code EDGE MCS7 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 + */ +extern const struct osmo_conv_code gsm0503_mcs7; + +/*! \brief structure describing convolutional code EDGE MCS8 + */ +extern const struct osmo_conv_code gsm0503_mcs8; + +/*! \brief structure describing convolutional code EDGE MCS9 + */ +extern const struct osmo_conv_code gsm0503_mcs9; diff --git a/include/osmocom/gsm/gsm0503_coding.h b/include/osmocom/gsm/gsm0503_coding.h new file mode 100644 index 0000000..76f6b7a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_coding.h @@ -0,0 +1,85 @@ +/* + * GSM 05.03 transcoding routines + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +#define GSM0503_GPRS_BURSTS_NBITS (116 * 4) +#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4) + +struct osmo_conv_code; + +enum gsm0503_egprs_mcs { + EGPRS_MCS0, + EGPRS_MCS1, + EGPRS_MCS2, + EGPRS_MCS3, + EGPRS_MCS4, + EGPRS_MCS5, + EGPRS_MCS6, + EGPRS_MCS7, + EGPRS_MCS8, + EGPRS_MCS9, + EGPRS_NUM_MCS, +}; + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len); +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, uint8_t *l2_data, + uint8_t l2_len); +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, + uint16_t nbits, uint8_t *usf_p, int *n_errors, int *n_bits_total); + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int net_order); +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order, + int efr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len); +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total); + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr); +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr); +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic); +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic); + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info); +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst); diff --git a/include/osmocom/gsm/gsm0503_interleaving.h b/include/osmocom/gsm/gsm0503_interleaving.h new file mode 100644 index 0000000..3f477cc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_interleaving.h @@ -0,0 +1,72 @@ +/* + * GSM 05.03 interleaving + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); diff --git a/include/osmocom/gsm/gsm0503_mapping.h b/include/osmocom/gsm/gsm0503_mapping.h new file mode 100644 index 0000000..74a7b83 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_mapping.h @@ -0,0 +1,55 @@ +/* + * GSM 05.03 mapping + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn); +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn); + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd); +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd); + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs5_burst_swap(sbit_t *eB); diff --git a/include/osmocom/gsm/gsm0503_parity.h b/include/osmocom/gsm/gsm0503_parity.h new file mode 100644 index 0000000..fa8bacc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_parity.h @@ -0,0 +1,35 @@ +/* + * GSM 05.03 parity + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +const struct osmo_crc64gen_code gsm0503_fire_crc40; +const struct osmo_crc16gen_code gsm0503_cs234_crc16; +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr; +const struct osmo_crc16gen_code gsm0503_mcs_crc12; +const struct osmo_crc8gen_code gsm0503_rach_crc6; +const struct osmo_crc16gen_code gsm0503_sch_crc10; +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3; +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8; +const struct osmo_crc8gen_code gsm0503_amr_crc6; diff --git a/include/osmocom/gsm/gsm0503_tables.h b/include/osmocom/gsm/gsm0503_tables.h new file mode 100644 index 0000000..dbabfb7 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_tables.h @@ -0,0 +1,71 @@ +/* + * GSM 05.03 tables + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; +extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8]; +extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8]; +extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8]; +extern const ubit_t gsm0503_usf2six[8][6]; +extern const ubit_t gsm0503_usf2twelve_ubit[8][12]; +extern const sbit_t gsm0503_usf2twelve_sbit[8][12]; +extern const uint8_t gsm0503_puncture_cs2[588]; +extern const uint8_t gsm0503_puncture_cs3[676]; +extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108]; +extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117]; +extern const uint8_t gsm0503_puncture_mcs1_p1[588]; +extern const uint8_t gsm0503_puncture_mcs1_p2[588]; +extern const uint8_t gsm0503_puncture_mcs2_p1[732]; +extern const uint8_t gsm0503_puncture_mcs2_p2[732]; +extern const uint8_t gsm0503_puncture_mcs3_p1[948]; +extern const uint8_t gsm0503_puncture_mcs3_p2[948]; +extern const uint8_t gsm0503_puncture_mcs3_p3[948]; +extern const uint8_t gsm0503_puncture_mcs4_p1[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p2[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p3[1116]; +extern const uint8_t gsm0503_puncture_mcs5_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs5_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs6_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs6_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135]; +extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162]; +extern const uint8_t gsm0503_puncture_mcs7_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p3[1404]; +extern const uint8_t gsm0503_puncture_mcs8_p1[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p2[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p3[1692]; +extern const uint8_t gsm0503_puncture_mcs9_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p3[1836]; +extern const uint16_t gsm0503_interleave_mcs5[1248]; +extern const uint8_t gsm0503_gsm_fr_map[76]; +extern const uint8_t gsm0503_gsm_efr_protected_bits[65]; +extern const ubit_t gsm0503_afs_ic_ubit[4][8]; +extern const sbit_t gsm0503_afs_ic_sbit[4][8]; +extern const ubit_t gsm0503_ahs_ic_ubit[4][4]; +extern const sbit_t gsm0503_ahs_ic_sbit[4][4]; +extern const uint8_t gsm0503_tch_hr_interleaving[228][2]; +extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36]; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..4d86566 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,16 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ + gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ + gsm0503_conv_edge.c gsm0503_tables.c \ + gsm0503_parity.c gsm0503_interleaving.c \ + gsm0503_mapping.c gsm0503_coding.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gprs_gea.c + libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +37,18 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: ../../utils/conv_gen.py $(AM_V_GEN)python2 ../../utils/conv_gen.py + +# Some dependencies from libosmocodec +gsm610.c: + $(AM_V_GEN)cp ../codec/gsm610.c ./ + +gsm620.c: + $(AM_V_GEN)cp ../codec/gsm620.c ./ + +gsm660.c: + $(AM_V_GEN)cp ../codec/gsm660.c ./ + +CLEANFILES = gsm0503_conv.c gsm610.c gsm620.c gsm660.c diff --git a/src/gsm/gsm0503_coding.c b/src/gsm/gsm0503_coding.c new file mode 100644 index 0000000..49cbee7 --- /dev/null +++ b/src/gsm/gsm0503_coding.c @@ -0,0 +1,2694 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * EGPRS coding limits + */ + +/* Max header size with parity bits */ +#define EGPRS_HDR_UPP_MAX 54 + +/* Max encoded header size */ +#define EGPRS_HDR_C_MAX 162 + +/* Max punctured header size */ +#define EGPRS_HDR_HC_MAX 160 + +/* Max data block size with parity bits */ +#define EGPRS_DATA_U_MAX 612 + +/* Max encoded data block size */ +#define EGPRS_DATA_C_MAX 1836 + +/* Max single block punctured data size */ +#define EGPRS_DATA_DC_MAX 1248 + +/* Dual block punctured data size */ +#define EGPRS_DATA_C1 612 +#define EGPRS_DATA_C2 EGPRS_DATA_C1 + +/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ +#define GSM_FR_BYTES 33 +/* TS 101318 Chapter 5.2: 112 bits, no sig */ +#define GSM_HR_BYTES 14 +/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ +#define GSM_EFR_BYTES 31 + +struct gsm0503_mcs_code { + uint8_t mcs; + uint8_t usf_len; + + /* Header coding */ + uint8_t hdr_len; + uint8_t hdr_code_len; + uint8_t hdr_punc_len; + const struct osmo_conv_code *hdr_conv; + const uint8_t *hdr_punc; + + /* Data coding */ + uint16_t data_len; + uint16_t data_code_len; + uint16_t data_punc_len; + const struct osmo_conv_code *data_conv; + const uint8_t *data_punc[3]; +}; + +/* + * EGPRS UL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_ul_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +/* + * EGPRS DL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_dl_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +static int osmo_conv_decode_ber(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output, + int *n_errors, int *n_bits_total) +{ + int res, i, coded_len; + ubit_t recoded[EGPRS_DATA_C_MAX]; + + res = osmo_conv_decode(code, input, output); + + if (n_bits_total || n_errors) { + coded_len = osmo_conv_encode(code, output, recoded); + OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len); + } + + /* Count bit errors */ + if (n_errors) { + *n_errors = 0; + for (i = 0; i < coded_len; i++) { + if (! ((recoded[i] && input[i] < 0) || + (!recoded[i] && input[i] > 0)) ) + *n_errors += 1; + } + } + + if (n_bits_total) + *n_bits_total = coded_len; + + return res; +} + + +static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB, + int *n_errors, int *n_bits_total) +{ + ubit_t conv[224]; + int rv; + + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 0; +} + +static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data) +{ + ubit_t conv[224]; + + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + return 0; +} + + +/* + * GSM xCCH block transcoding + */ + +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[456]; + int i; + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL); + + gsm0503_xcch_deinterleave(cB, iB); + + return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total); +} + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data) +{ + ubit_t iB[456], cB[456], hl = 1, hn = 1; + int i; + + _xcch_encode_cB(cB, l2_data); + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn); + + return 0; +} + +/* + * EGPRS PDTCH UL block decoding + */ + +/* + * Type 3 - MCS-1,2,3,4 + * Unmapping and deinterleaving + */ +static int egprs_type3_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t iB[456], q[8]; + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + q + i * 2, q + i * 2 + 1); + } + + gsm0503_mcs1_ul_deinterleave(hc, dc, iB); + + return 0; +} + +/* + * Type 2 - MCS-5,6 + * Unmapping and deinterleaving + */ +static int egprs_type2_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_DC_MAX]; + + for (i=0; i<4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs5_ul_burst_unmap(di, burst, hi, i); + } + + gsm0503_mcs5_ul_deinterleave(hc, dc, hi, di); + + return 0; +} + +/* + * Type 1 - MCS-7,8,9 + * Unmapping and deinterleaving - Note that MCS-7 interleaver is unique + */ +static int egprs_type1_unmap(const sbit_t *bursts, sbit_t *hc, + sbit_t *c1, sbit_t *c2, int msc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_C1 * 2]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs7_ul_burst_unmap(di, burst, hi, i); + } + + if (msc == EGPRS_MCS7) + gsm0503_mcs7_ul_deinterleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_ul_deinterleave(hc, c1, c2, hi, di); + + return 0; +} + +union gprs_rlc_ul_hdr_egprs { + struct gprs_rlc_ul_header_egprs_1 type1; + struct gprs_rlc_ul_header_egprs_2 type2; + struct gprs_rlc_ul_header_egprs_3 type3; +}; + +/* + * Decode EGPRS UL header section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + */ +static int _egprs_decode_hdr(const sbit_t *hc, int mcs, + union gprs_rlc_ul_hdr_egprs *hdr) +{ + sbit_t C[EGPRS_HDR_C_MAX]; + ubit_t upp[EGPRS_HDR_UPP_MAX]; + int i, j, rc; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_ul_codes[mcs]; + + /* Skip depuncturing on MCS-5,6 header */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(C, hc, code->hdr_code_len); + goto hdr_conv_decode; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + i = code->hdr_code_len - 1; + j = code->hdr_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->hdr_punc[i]) + C[i] = hc[j--]; + else + C[i] = 0; + } + +hdr_conv_decode: + osmo_conv_decode_ber(code->hdr_conv, C, upp, NULL, NULL); + rc = osmo_crc8gen_check_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + if (rc) + return -1; + + osmo_ubit2pbit_ext((pbit_t *) hdr, 0, upp, 0, code->hdr_len, 1); + + return 0; +} + +/* + * Blind MCS header decoding based on burst length and CRC validation. + * Ignore 'q' value coding indentification. This approach provides + * the strongest chance of header recovery. + */ +static int egprs_decode_hdr(union gprs_rlc_ul_hdr_egprs *hdr, + const sbit_t *bursts, uint16_t nbits) +{ + int rc; + sbit_t hc[EGPRS_HDR_HC_MAX]; + + if (nbits == GSM0503_GPRS_BURSTS_NBITS) { + /* MCS-1,2,3,4 */ + egprs_type3_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS1, hdr); + if (!rc) + return EGPRS_HDR_TYPE3; + } else if (nbits == GSM0503_EGPRS_BURSTS_NBITS) { + /* MCS-5,6 */ + egprs_type2_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS5, hdr); + if (!rc) + return EGPRS_HDR_TYPE2; + + /* MCS-7,8,9 */ + egprs_type1_unmap(bursts, hc, NULL, NULL, EGPRS_MCS7); + rc = _egprs_decode_hdr(hc, EGPRS_MCS7, hdr); + if (!rc) + return EGPRS_HDR_TYPE1; + } + + return -1; +} + +/* + * Parse EGPRS UL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_ul_cps(struct egprs_cps *cps, + union gprs_rlc_ul_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = (hdr->type2.cps_lo << 2) | hdr->type2.cps_hi; + break; + case EGPRS_HDR_TYPE3: + bits = (hdr->type3.cps_lo << 2) | hdr->type3.cps_hi; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +#define NUM_BYTES(N) ((N + 8 - 1) / 8) + +/* + * Decode EGPRS UL data section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + * 4. Block combining (MCS-7,8,9 only) + */ +static int egprs_decode_data(uint8_t *l2_data, sbit_t *c, + int mcs, int p, int blk, + int *n_errors, int *n_bits_total) +{ + ubit_t u[EGPRS_DATA_U_MAX]; + sbit_t C[EGPRS_DATA_C_MAX]; + + int i, j, rc, data_len; + struct gsm0503_mcs_code *code; + + if (blk && mcs < EGPRS_MCS7) { + /* Invalid MCS-X block state */ + return -1; + } + + code = &gsm0503_mcs_ul_codes[mcs]; + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + /* + * MCS-1,6 - single block processing + * MCS-7,9 - dual block processing + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + i = code->data_code_len - 1; + j = code->data_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->data_punc[p][i]) + C[i] = c[j--]; + else + C[i] = 0; + } + + osmo_conv_decode_ber(code->data_conv, C, u, n_errors, n_bits_total); + rc = osmo_crc16gen_check_bits(&gsm0503_mcs_crc12, u, + data_len, u + data_len); + if (rc) + return -1; + + /* Offsets output pointer on the second block of Type 1 MCS */ + osmo_ubit2pbit_ext(l2_data, code->hdr_len + blk * data_len, + u, 0, data_len, 1); + + /* Return the number of bytes required for the bit message */ + return NUM_BYTES(code->hdr_len + code->data_len); +} + +/* + * Decode EGPRS UL message + * + * 1. Header section decoding + * 2. Extract CPS settings + * 3. Burst unmapping and deinterleaving + * 4. Data section decoding + */ +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, uint16_t nbits, + uint8_t *usf_p, int *n_errors, int *n_bits_total) +{ + sbit_t dc[EGPRS_DATA_DC_MAX]; + sbit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + int type, rc; + struct egprs_cps cps; + union gprs_rlc_ul_hdr_egprs *hdr; + + if ((nbits != GSM0503_GPRS_BURSTS_NBITS) && + (nbits != GSM0503_EGPRS_BURSTS_NBITS)) { + /* Invalid EGPRS bit length */ + return -1; + } + + hdr = (union gprs_rlc_ul_hdr_egprs *) l2_data; + type = egprs_decode_hdr(hdr, bursts, nbits); + if (egprs_parse_ul_cps(&cps, hdr, type) < 0) + return -1; + + switch (cps.mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + egprs_type3_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + egprs_type2_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + egprs_type1_unmap(bursts, NULL, c1, c2, cps.mcs); + break; + default: + /* Invalid MCS-X */ + return -1; + } + + /* Decode MCS-X block, where X = cps.mcs */ + if (cps.mcs < EGPRS_MCS7) { + rc = egprs_decode_data(l2_data, dc, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + } else { + /* MCS-7,8,9 block 1 */ + rc = egprs_decode_data(l2_data, c1, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + + /* MCS-7,8,9 block 2 */ + rc = egprs_decode_data(l2_data, c2, cps.mcs, cps.p[1], + 1, n_errors, n_bits_total); + if (rc < 0) + return -1; + } + + return rc; +} + +/* + * GSM PDTCH block transcoding + */ + +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[676], hl_hn[8]; + ubit_t conv[456]; + int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */ + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j])); + + if (i == 0 || k < best) { + best = k; + cs = i+1; + } + } + + gsm0503_xcch_deinterleave(cB, iB); + + switch (cs) { + case 1: + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 23; + case 2: + for (i = 587, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs2[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs2, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 271, conv + 3 + 271); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1); + + return 34; + case 3: + for (i = 675, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs3[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs3, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 315, conv + 3 + 315); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1); + + return 40; + case 4: + for (i = 12; i < 456; i++) + conv[i] = (cB[i] < 0) ? 1 : 0; + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 12; j++) + k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[9] = usf & 1; + conv[10] = (usf >> 1) & 1; + conv[11] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 9, 431, conv + 9 + 431); + if (rv) { + *n_bits_total = 456 - 12; + *n_errors = *n_bits_total; + return -1; + } + + *n_bits_total = 456 - 12; + *n_errors = 0; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1); + + return 54; + default: + *n_bits_total = 0; + *n_errors = 0; + break; + } + + return -1; +} + +/* + * EGPRS PDTCH UL block encoding + */ +static int egprs_type3_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + ubit_t iB[456]; + const ubit_t *hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + gsm0503_mcs1_dl_interleave(gsm0503_usf2six[usf], hc, dc, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return 0; +} + +static int egprs_type2_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_DC_MAX]; + + gsm0503_mcs5_dl_interleave(hc, dc, hi, di); + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs5_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_type1_map(ubit_t *bursts, ubit_t *hc, + ubit_t *c1, ubit_t *c2, int usf, int mcs) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_C1 * 2]; + + if (mcs == EGPRS_MCS7) + gsm0503_mcs7_dl_interleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_dl_interleave(hc, c1, c2, hi, di); + + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs7_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_encode_hdr(ubit_t *hc, uint8_t *l2_data, int mcs) +{ + int i, j; + ubit_t upp[EGPRS_HDR_UPP_MAX], C[EGPRS_HDR_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + osmo_pbit2ubit_ext(upp, 0, l2_data, code->usf_len, code->hdr_len, 1); + osmo_crc8gen_set_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + + osmo_conv_encode(code->hdr_conv, upp, C); + + /* MCS-5,6 header direct puncture instead of table */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(hc, C, code->hdr_code_len); + hc[99] = hc[98]; + return 0; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->hdr_code_len; i++) { + if (!code->hdr_punc[i]) + hc[j++] = C[i]; + } + + return 0; +} + +static int egprs_encode_data(ubit_t *c, uint8_t *l2_data, + int mcs, int p, int blk) +{ + int i, j, data_len; + ubit_t u[EGPRS_DATA_U_MAX], C[EGPRS_DATA_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + /* + * Dual block - MCS-7,8,9 + * Single block - MCS-1,2,3,4,5,6 + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + osmo_pbit2ubit_ext(u, 0, l2_data, + code->usf_len + code->hdr_len + blk * data_len, data_len, 1); + + osmo_crc16gen_set_bits(&gsm0503_mcs_crc12, u, data_len, u + data_len); + + osmo_conv_encode(code->data_conv, u, C); + + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->data_code_len; i++) { + if (!code->data_punc[p][i]) + c[j++] = C[i]; + } + + return 0; +} + +union gprs_rlc_dl_hdr_egprs { + struct gprs_rlc_dl_header_egprs_1 type1; + struct gprs_rlc_dl_header_egprs_2 type2; + struct gprs_rlc_dl_header_egprs_3 type3; +}; + +/* + * Parse EGPRS DL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_dl_cps(struct egprs_cps *cps, + union gprs_rlc_dl_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = hdr->type2.cps; + break; + case EGPRS_HDR_TYPE3: + bits = hdr->type3.cps; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * EGPRS DL message encoding + */ +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, + uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t hc[EGPRS_DATA_C_MAX], dc[EGPRS_DATA_DC_MAX]; + ubit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + uint8_t mcs; + struct egprs_cps cps; + union gprs_rlc_dl_hdr_egprs *hdr; + + switch (l2_len) { + case 27: + mcs = EGPRS_MCS1; + break; + case 33: + mcs = EGPRS_MCS2; + break; + case 42: + mcs = EGPRS_MCS3; + break; + case 49: + mcs = EGPRS_MCS4; + break; + case 60: + mcs = EGPRS_MCS5; + break; + case 78: + mcs = EGPRS_MCS6; + break; + case 118: + mcs = EGPRS_MCS7; + break; + case 142: + mcs = EGPRS_MCS8; + break; + case 154: + mcs = EGPRS_MCS9; + break; + default: + return -1; + } + + /* Read header for USF and puncturing matrix selection. */ + hdr = (union gprs_rlc_dl_hdr_egprs *) l2_data; + + switch (mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + /* Check for valid CPS and matching MCS to message size */ + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE3) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type3_map(bursts, hc, dc, hdr->type3.usf); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE2) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type2_map(bursts, hc, dc, hdr->type2.usf); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE1) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(c1, l2_data, mcs, cps.p[0], 0); + egprs_encode_data(c2, l2_data, mcs, cps.p[1], 1); + egprs_type1_map(bursts, hc, c1, c2, hdr->type1.usf, mcs); + break; + } + + return mcs >= EGPRS_MCS5 ? GSM0503_EGPRS_BURSTS_NBITS : + GSM0503_GPRS_BURSTS_NBITS; + +bad_header: + /* Invalid EGPRS MCS-X header */ + return -1; +} + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t iB[456], cB[676]; + const ubit_t *hl_hn; + ubit_t conv[334]; + int i, j, usf; + + switch (l2_len) { + case 23: + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[0]; + + break; + case 34: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 271, conv + 3 + 271); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs2, conv, cB); + + for (i = 0, j = 0; i < 588; i++) + if (!gsm0503_puncture_cs2[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[1]; + + break; + case 40: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 315, conv + 3 + 315); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs3, conv, cB); + + for (i = 0, j = 0; i < 676; i++) + if (!gsm0503_puncture_cs3[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[2]; + + break; + case 54: + osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9, + 431, cB + 9 + 431); + + memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + break; + default: + return -1; + } + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return GSM0503_GPRS_BURSTS_NBITS; +} + + +/* + * GSM TCH/F FR/EFR transcoding + */ + +static void tch_fr_reassemble(uint8_t *tch_data, + ubit_t *b_bits, int net_order) +{ + int i, j, k, l, o; + + tch_data[0] = 0xd << 4; + memset(tch_data + 1, 0, 32); + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); + + return; + } + + /* reassemble d-bits */ + i = 0; /* counts bits */ + j = 4; /* counts output bits */ + k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset input bits */ + while (i < 260) { + tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7))); + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l]-1; + } + i++; + j++; + } +} + +static void tch_fr_disassemble(ubit_t *b_bits, + uint8_t *tch_data, int net_order) +{ + int i, j, k, l, o; + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + + return; + } + + i = 0; /* counts bits */ + j = 4; /* counts input bits */ + k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset output bits */ + while (i < 260) { + b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l] - 1; + } + i++; + j++; + } +} + +static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0x00; /* F = 0, FT = 000 */ + memset(tch_data + 1, 0, 14); + + for (i = 0, j = 8; i < 112; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 8; i < 112; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0xc << 4; + memset(tch_data + 1, 0, 30); + + for (i = 0, j = 4; i < 244; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 4; i < 244; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len) +{ + int i, j; + + memset(tch_data, 0, (len + 7) >> 3); + + for (i = 0, j = 0; i < len; i++, j++) + tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7))); +} + +static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len) +{ + int i, j; + + for (i = 0, j = 0; i < len; i++, j++) + d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm610_bitorder[i]] = d_bits[i]; +} + +static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm610_bitorder[i]]; +} + +static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + const uint16_t *map; + + if (!b_bits[34] && !b_bits[35]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + d_bits[i] = b_bits[map[i]]; +} + +static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm660_bitorder[i]] = d_bits[i]; +} + +static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm660_bitorder[i]]; +} + +static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 65; i++) + b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1]; +} + +static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + int i; + + for (i = 0; i < 91; i++) { + d[i << 1] = u[i]; + d[(i << 1) + 1] = u[184 - i]; + } + + for (i = 0; i < 3; i++) + p[i] = u[91 + i]; +} + +static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + int i; + + for (i = 0; i < 91; i++) { + u[i] = d[i << 1]; + u[184 - i] = d[(i << 1) + 1]; + } + + for (i = 0; i < 3; i++) + u[91 + i] = p[i]; +} + +static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + memcpy(d, u, 95); + memcpy(p, u + 95, 3); +} + +static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + memcpy(u, d, 95); + memcpy(u + 95, p, 3); +} + +static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p) +{ + memcpy(w, s, 71); + w[71] = w[72] = s[69]; + memcpy(w + 73, s + 71, 50); + w[123] = w[124] = s[119]; + memcpy(w + 125, s + 121, 53); + w[178] = w[179] = s[172]; + memcpy(w + 180, s + 174, 50); + w[230] = w[231] = s[222]; + memcpy(w + 232, s + 224, 20); + memcpy(w + 252, p, 8); +} + +static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w) +{ + int sum; + + memcpy(s, w, 71); + sum = s[69] + w[71] + w[72]; + s[69] = (sum > 2); + memcpy(s + 71, w + 73, 50); + sum = s[119] + w[123] + w[124]; + s[119] = (sum > 2); + memcpy(s + 121, w + 125, 53); + sum = s[172] + w[178] + w[179]; + s[172] = (sum > 2); + memcpy(s + 174, w + 180, 50); + sum = s[220] + w[230] + w[231]; + s[222] = (sum > 2); + memcpy(s + 224, w + 232, 20); + memcpy(p, w + 252, 8); +} + +static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot) +{ + memcpy(u, d, prot); + memcpy(u + prot, p, 6); + memcpy(u + prot + 6, d + prot, len - prot); +} + +static void tch_amr_unmerge(ubit_t *d, ubit_t *p, + ubit_t *u, int len, int prot) +{ + memcpy(d, u, prot); + memcpy(p, u+prot, 6); + memcpy(d + prot, u + prot + 6, len - prot); +} + +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, + int net_order, int efr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[185], s[244], w[260], b[65], d[260], p[8]; + int i, rv, len, steal = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return 23; + } + + osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total); + + tch_fr_unreorder(d, p, conv); + + for (i = 0; i < 78; i++) + d[i + 182] = (cB[i + 378] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p); + if (rv) { + /* Error checking CRC8 for the FR part of an EFR/FR frame */ + return -1; + } + + if (efr) { + tch_efr_d_to_w(w, d); + + tch_efr_unreorder(s, p, w); + + tch_efr_protected(s, b); + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p); + if (rv) { + /* Error checking CRC8 for the EFR part of an EFR frame */ + return -1; + } + + tch_efr_reassemble(tch_data, s); + + len = GSM_EFR_BYTES; + } else { + tch_fr_d_to_b(w, d); + + tch_fr_reassemble(tch_data, w, net_order); + + len = GSM_FR_BYTES; + } + + return len; +} + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, + int len, int net_order) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[185], w[260], b[65], s[244], d[260], p[8]; + int i; + + switch (len) { + case GSM_EFR_BYTES: /* TCH EFR */ + + tch_efr_disassemble(s, tch_data); + + tch_efr_protected(s, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p); + + tch_efr_reorder(w, s, p); + + tch_efr_w_to_d(d, w); + + goto coding_efr_fr; + case GSM_FR_BYTES: /* TCH FR */ + tch_fr_disassemble(w, tch_data, net_order); + + tch_fr_b_to_d(d, w); + +coding_efr_fr: + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p); + + tch_fr_reorder(conv, d, p); + + memcpy(cB + 378, d + 182, 78); + + osmo_conv_encode(&gsm0503_tch_fr, conv, cB); + + h = 0; + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + break; + default: + return -1; + } + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; +} + +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i, rv, steal = 0; + + /* Only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* If we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total); + + tch_hr_unreorder(d, p, conv); + + for (i = 0; i < 17; i++) + d[i + 95] = (cB[i + 211] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + if (rv) { + /* Error checking CRC8 for an HR frame */ + return -1; + } + + tch_hr_d_to_b(b, d); + + tch_hr_reassemble(tch_data, b); + + return 15; +} + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i; + + switch (len) { + case 15: /* TCH HR */ + tch_hr_disassemble(b, tch_data); + + tch_hr_b_to_d(d, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + + tch_hr_reorder(conv, d, p); + + osmo_conv_encode(&gsm0503_tch_hr, conv, cB); + + memcpy(cB + 211, d + 95, 17); + + h = 0; + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 1); + } + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i=0; i<6; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + for (i=2; i<4; i++) { + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + } + + break; + default: + return -1; + } + + return 0; +} + +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + *n_errors = 0; *n_bits_total = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 7: /* TCH/AFS12.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 244, 81); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p); + if (rv) { + /* Error checking CRC8 for an AMR 12.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 244); + + len = 31; + + break; + case 6: /* TCH/AFS10.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 204, 65); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p); + if (rv) { + /* Error checking CRC8 for an AMR 10.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 204); + + len = 26; + + break; + case 5: /* TCH/AFS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 159, 75); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AFS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 148, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AFS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 134, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AFS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 118, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AFS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 103, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AFS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 95, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 448; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + goto facch; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID is not in codec list! */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID is not in codec list! */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 7: /* TCH/AFS12.2 */ + if (len != 31) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 244); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p); + + tch_amr_merge(conv, d, p, 244, 81); + + osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8); + + break; + case 6: /* TCH/AFS10.2 */ + if (len != 26) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 204); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p); + + tch_amr_merge(conv, d, p, 204, 65); + + osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8); + + break; + case 5: /* TCH/AFS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p); + + tch_amr_merge(conv, d, p, 159, 75); + + osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8); + + break; + case 4: /* TCH/AFS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 148, 61); + + osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8); + + break; + case 3: /* TCH/AFS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 134, 55); + + osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8); + + break; + case 2: /* TCH/AFS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 118, 55); + + osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8); + + break; + case 1: /* TCH/AFS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 103, 49); + + osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8); + + break; + case 0: /* TCH/AFS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 95, 39); + + osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 8); + +facch: + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + + /* only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* if we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 4; j++) + k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 5: /* TCH/AHS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 123, 67); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + for (i = 0; i < 36; i++) + d[i + 123] = (cB[i + 192] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AHS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 120, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + for (i = 0; i < 28; i++) + d[i + 120] = (cB[i + 200] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AHS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 110, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + for (i = 0; i < 24; i++) + d[i + 110] = (cB[i + 204] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AHS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 102, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + for (i = 0; i < 16; i++) + d[i + 102] = (cB[i + 212] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AHS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 91, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 91] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AHS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 83, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 83] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 159; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 6; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], + &h, i >> 2); + for (i = 2; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + + return 0; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID %d not in codec list */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID %d not in codec list */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 5: /* TCH/AHS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p); + + tch_amr_merge(conv, d, p, 123, 67); + + osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4); + + memcpy(cB + 192, d + 123, 36); + + break; + case 4: /* TCH/AHS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 120, 61); + + osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4); + + memcpy(cB + 200, d + 120, 28); + + break; + case 3: /* TCH/AHS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 110, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4); + + memcpy(cB + 204, d + 110, 24); + + break; + case 2: /* TCH/AHS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 102, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4); + + memcpy(cB + 212, d + 102, 16); + + break; + case 1: /* TCH/AHS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 91, 49); + + osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4); + + memcpy(cB + 216, d + 91, 12); + + break; + case 0: /* TCH/AHS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 83, 39); + + osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4); + + memcpy(cB + 216, d + 83, 12); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 4); + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1); + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +/* + * GSM RACH transcoding + */ + +/* + * GSM RACH apply BSIC to parity + * + * p(j) = p(j) xor b(j) j = 0, ..., 5 + * b(0) = MSB of PLMN colour code + * b(5) = LSB of BS colour code + */ + +static int rach_apply_bsic(ubit_t *d, uint8_t bsic) +{ + int i; + + /* Apply it */ + for (i = 0; i < 6; i++) + d[8 + i] ^= ((bsic >> (5 - i)) & 1); + + return 0; +} + +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic) +{ + ubit_t conv[14]; + int rv; + + osmo_conv_decode(&gsm0503_rach, burst, conv); + + rach_apply_bsic(conv, bsic); + + rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + if (rv) + return -1; + + osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1); + + return 0; +} + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic) +{ + ubit_t conv[14]; + + osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1); + + osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + + rach_apply_bsic(conv, bsic); + + osmo_conv_encode(&gsm0503_rach, conv, burst); + + return 0; +} + + +/* + * GSM SCH transcoding + */ + +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst) +{ + ubit_t conv[35]; + int rv; + + osmo_conv_decode(&gsm0503_sch, burst, conv); + + rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + if (rv) + return -1; + + osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1); + + return 0; +} + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info) +{ + ubit_t conv[35]; + + osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1); + + osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + + osmo_conv_encode(&gsm0503_sch, conv, burst); + + return 0; +} diff --git a/src/gsm/gsm0503_conv_edge.c b/src/gsm/gsm0503_conv_edge.c new file mode 100644 index 0000000..a542323 --- /dev/null +++ b/src/gsm/gsm0503_conv_edge.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2016 Tom Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +static const uint8_t conv_mcs_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, +}; + +static const uint8_t conv_mcs_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + + +const struct osmo_conv_code gsm0503_mcs1_dl_hdr = { + .N = 3, + .K = 7, + .len = 36, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1_ul_hdr = { + .N = 3, + .K = 7, + .len = 39, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1 = { + .N = 3, + .K = 7, + .len = 190, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs2 = { + .N = 3, + .K = 7, + .len = 238, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs3 = { + .N = 3, + .K = 7, + .len = 310, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs4 = { + .N = 3, + .K = 7, + .len = 366, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_dl_hdr = { + .N = 3, + .K = 7, + .len = 33, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_ul_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs6 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_dl_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_ul_hdr = { + .N = 3, + .K = 7, + .len = 54, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs8 = { + .N = 3, + .K = 7, + .len = 558, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs9 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; diff --git a/src/gsm/gsm0503_interleaving.c b/src/gsm/gsm0503_interleaving.c new file mode 100644 index 0000000..0c1b8a0 --- /dev/null +++ b/src/gsm/gsm0503_interleaving.c @@ -0,0 +1,574 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include +#include + +/* + * GSM xCCH interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 4 blocks of 114 bits: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 4) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (u) { + for (k=0; k<12; k++) + u[k] = c[k]; + } + + if (hc) { + for (k=12; k<80; k++) + hc[k - 12] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<12; k++) + c[k] = up[k]; + for (k=12; k<80; k++) + c[k] = hc[k - 12]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (hc) { + for (k=0; k<80; k++) + hc[k] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<80; k++) + c[k] = hc[k]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +/* + * GSM TCH FR/EFR/AFS interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 8 blocks of 114 bits, + * where even bits of the first 4 blocks and odd bits of the last 4 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 8) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +/* + * GSM TCH HR/AHS interleaving and burst mapping + * + * Interleaving: + * + * Given 288 coded input bits, form 4 blocks of 114 bits, + * where even bits of the first 2 blocks and odd bits of the last 2 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 227 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 2n + b + * j, b = table[k]; + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + iB[B * 114 + j] = cB[k]; + } +} + diff --git a/src/gsm/gsm0503_mapping.c b/src/gsm/gsm0503_mapping.c new file mode 100644 index 0000000..c2079b9 --- /dev/null +++ b/src/gsm/gsm0503_mapping.c @@ -0,0 +1,291 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn) +{ + memcpy(iB, eB, 57); + memcpy(iB+57, eB+59, 57); + + if (hl) + *hl = eB[57]; + + if (hn) + *hn = eB[58]; +} + +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn) +{ + memcpy(eB, iB, 57); + memcpy(eB+59, iB+57, 57); + + if (hl) + eB[57] = *hl; + if (hn) + eB[58] = *hn; +} + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (iB) { + for (i=odd; i<57; i+=2) + iB[i] = eB[i]; + for (i=58-odd; i<114; i+=2) + iB[i] = eB[i+2]; + } + + if (h) { + if (!odd) + *h = eB[58]; + else + *h = eB[57]; + } +} + +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (eB) { + for (i=odd; i<57; i+=2) + eB[i] = iB[i]; + for (i=58-odd; i<114; i+=2) + eB[i+2] = iB[i]; + } + + if (h) { + if (!odd) + eB[58] = *h; + else + eB[57] = *h; + } +} + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<168; j++) + eB[j] = hi[25*B+j-156]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<192; j++) + eB[j] = hi[25*B+j-167]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<168; j++) + hi[25*B+j-156] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<192; j++) + hi[25*B+j-167] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<174; j++) + eB[j] = hi[34*B+j-156]; + for (j=174; j<176; j++) + eB[j] = 0; + for (j=176; j<192; j++) + eB[j] = hi[34*B+j-158]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<174; j++) + hi[34*B+j-156] = eB[j]; + for (j=176; j<192; j++) + hi[34*B+j-158] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<168; j++) + eB[j] = hi[31*B+j-153]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<195; j++) + eB[j] = hi[31*B+j-164]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<168; j++) + hi[31*B+j-153] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<195; j++) + hi[31*B+j-164] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<174; j++) + eB[j] = hi[40*B+j-153]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<195; j++) + eB[j] = hi[40*B+j-155]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<174; j++) + hi[40*B+j-153] = eB[j]; + + for (j=176; j<195; j++) + hi[40*B+j-155] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs5_burst_swap(sbit_t *eB) +{ + sbit_t t[14]; + + t[0] = eB[155]; + t[1] = eB[158]; + t[2] = eB[161]; + t[3] = eB[164]; + t[4] = eB[167]; + t[5] = eB[170]; + t[6] = eB[173]; + t[7] = eB[195]; + t[8] = eB[196]; + t[9] = eB[198]; + t[10] = eB[199]; + t[11] = eB[201]; + t[12] = eB[202]; + t[13] = eB[204]; + + eB[155] = eB[142]; + eB[158] = eB[144]; + eB[161] = eB[145]; + eB[164] = eB[147]; + eB[167] = eB[148]; + eB[170] = eB[150]; + eB[173] = eB[151]; + eB[195] = eB[176]; + eB[196] = eB[179]; + eB[198] = eB[182]; + eB[199] = eB[185]; + eB[201] = eB[188]; + eB[202] = eB[191]; + eB[204] = eB[194]; + + eB[142] = t[0]; + eB[144] = t[1]; + eB[145] = t[2]; + eB[147] = t[3]; + eB[148] = t[4]; + eB[150] = t[5]; + eB[151] = t[6]; + eB[176] = t[7]; + eB[179] = t[8]; + eB[182] = t[9]; + eB[185] = t[10]; + eB[188] = t[11]; + eB[191] = t[12]; + eB[194] = t[13]; +} diff --git a/src/gsm/gsm0503_parity.c b/src/gsm/gsm0503_parity.c new file mode 100644 index 0000000..c9cfba4 --- /dev/null +++ b/src/gsm/gsm0503_parity.c @@ -0,0 +1,145 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +/* + * GSM (SACCH) parity (FIRE code) + * + * g(x) = (x^23 + 1)(x^17 + x^3 + 1) + * = x^40 + x^26 + x^23 + x^17 + x^3 + a1 + */ + +const struct osmo_crc64gen_code gsm0503_fire_crc40 = { + .bits = 40, + .poly = 0x0004820009ULL, + .init = 0x0000000000ULL, + .remainder = 0xffffffffffULL, +}; + + +/* + * GSM PDTCH CS-2, CS-3, CS-4 parity + * + * g(x) = x^16 + x^12 + x^5 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_cs234_crc16 = { + .bits = 16, + .poly = 0x1021, + .init = 0x0000, + .remainder = 0xffff, +}; + +/* + * EDGE MCS header parity + * + */ + +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = { + .bits = 8, + .poly = 0x49, + .init = 0x00, + .remainder = 0xff, +}; + +/* + * EDGE MCS data parity + * + */ + +const struct osmo_crc16gen_code gsm0503_mcs_crc12 = { + .bits = 12, + .poly = 0x0d31, + .init = 0x0000, + .remainder = 0x0fff, +}; + +/* + * GSM RACH parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_rach_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + + +/* + * GSM SCH parity + * + * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_sch_crc10 = { + .bits = 10, + .poly = 0x175, + .init = 0x000, + .remainder = 0x3ff, +}; + + +/* + * GSM TCH FR/HR/EFR parity + * + * g(x) = x^3 + x + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = { + .bits = 3, + .poly = 0x3, + .init = 0x0, + .remainder = 0x7, +}; + +/* + * GSM TCH EFR parity + * + * g(x) = x^8 + x^4 + x^3 + x^2 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = { + .bits = 8, + .poly = 0x1d, + .init = 0x00, + .remainder = 0x00, +}; + +/* + * GSM AMR parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_amr_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + diff --git a/src/gsm/gsm0503_tables.c b/src/gsm/gsm0503_tables.c new file mode 100644 index 0000000..95132b1 --- /dev/null +++ b/src/gsm/gsm0503_tables.c @@ -0,0 +1,1732 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = { + { 1,1, 1,1, 1,1, 1,1 }, + { 1,1, 0,0, 1,0, 0,0 }, + { 0,0, 1,0, 0,0, 0,1 }, + { 0,0, 0,1, 0,1, 1,0 }, +}; + +const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = { + { 0,0, 0,1, 0,1, 1,0 }, + { 0,0, 0,0, 0,0, 0,0 }, + { 1,1, 1,0, 0,1, 1,1 }, +}; + +const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = { + { -127,-127, -127,-127, -127,-127, -127,-127 }, + { -127,-127, 127, 127, -127, 127, 127, 127 }, + { 127, 127, -127, 127, 127, 127, 127,-127 }, + { 127, 127, 127,-127, 127,-127, -127, 127 }, +}; + +const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = { + { 127, 127, 127,-127, 127,-127, -127, 127 }, + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, -127, 127, 127,-127, -127,-127 }, +}; + +const ubit_t gsm0503_usf2six[8][6] = { + { 0,0,0, 0,0,0 }, + { 1,0,0, 1,0,1 }, + { 0,1,0, 1,1,0 }, + { 1,1,0, 0,1,1 }, + { 0,0,1, 0,1,1 }, + { 1,0,1, 1,1,0 }, + { 0,1,1, 1,0,1 }, + { 1,1,1, 0,0,0 }, +}; + +const ubit_t gsm0503_usf2twelve_ubit[8][12] = { + { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }, + { 1,1,0, 1,0,0, 0,0,1, 0,1,1 }, + { 0,0,1, 1,0,1, 1,1,0, 1,1,0 }, + { 1,1,1, 0,0,1, 1,1,1, 1,0,1 }, + { 0,0,0, 0,1,1, 0,1,1, 1,0,1 }, + { 1,1,0, 1,1,1, 0,1,0, 1,1,0 }, + { 0,0,1, 1,1,0, 1,0,1, 0,1,1 }, + { 1,1,1, 0,1,0, 1,0,0, 0,0,0 }, +}; + +const sbit_t gsm0503_usf2twelve_sbit[8][12] = { + { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 }, + { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 }, + { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 }, + { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 }, + { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 }, + { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 }, + { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 }, +}; + +const uint8_t gsm0503_puncture_cs2[588] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1 +}; + +const uint8_t gsm0503_puncture_cs3[676] = { + 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0 +}; + +const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = { + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p1[588] = { + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p2[588] = { + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p1[732] = { + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p2[732] = { + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p1[948] = { + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p2[948] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p3[948] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs4_p1[1116] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p2[1116] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p3[1116] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs5_p1[1404] = { + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs5_p2[1404] = { + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs6_p1[1836] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs6_p2[1836] = { + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0, + 0,1,0,0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p1[1404] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs7_p2[1404] = { + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p3[1404] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p1[1692] = { + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs8_p2[1692] = { + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p3[1692] = { + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p1[1836] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p2[1836] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p3[1836] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, +}; + +const uint16_t gsm0503_interleave_mcs5[1248] = { + 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428, + 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968, + 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575, + 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688, + 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440, + 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980, + 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942, + 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700, + 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452, + 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414, + 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954, + 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712, + 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101, + 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420, + 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960, + 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567, + 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695, + 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432, + 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972, + 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937, + 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707, + 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444, + 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409, + 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949, + 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719, + 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096, + 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427, + 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967, + 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574, + 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687, + 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439, + 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979, + 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944, + 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699, + 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451, + 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416, + 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956, + 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711, + 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103, + 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422, + 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962, + 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569, + 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694, + 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434, + 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974, + 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936, + 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706, + 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446, + 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408, + 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948, + 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718, + 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095, + 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426, + 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966, + 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573, + 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689, + 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438, + 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978, + 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943, + 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701, + 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450, + 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415, + 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955, + 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713, + 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102, + 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421, + 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961, + 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568, + 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693, + 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433, + 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973, + 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938, + 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705, + 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445, + 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410, + 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950, + 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717, + 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097, +}; + +/* this corresponds to the bit-lengths of the individual codec + * parameters as indicated in Table 1.1 of TS 06.10 */ +const uint8_t gsm0503_gsm_fr_map[76] = { + 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* this table describes the 65 most importaint bits from EFR coded + * bits as indicated in TS 05.03 (3.1.1.1) */ +const uint8_t gsm0503_gsm_efr_protected_bits[65] = { + 39, 40, 41, 42, 43, 44, 48, 87, 45, 2, + 3, 8, 10, 18, 19, 24, 46, 47,142,143, + 144,145,146,147, 92, 93,195,196, 98,137, + 148, 94,197,149,150, 95,198, 4, 5, 11, + 12, 16, 9, 6, 7, 13, 17, 20, 96,199, + 1, 14, 15, 21, 25, 26, 28,151,201,190, + 240, 88,138,191,241 +}; + +/* Encoded in-band data for speech frames */ +const ubit_t gsm0503_afs_ic_ubit[4][8] = { + { 0,0,0,0,0,0,0,0 }, + { 0,1,0,1,1,1,0,1 }, + { 1,0,1,1,1,0,1,0 }, + { 1,1,1,0,0,1,1,1 }, +}; + +const sbit_t gsm0503_afs_ic_sbit[4][8] = { + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { 127,-127, 127,-127,-127,-127, 127,-127 }, + { -127, 127,-127,-127,-127, 127,-127, 127 }, + { -127,-127,-127, 127, 127,-127,-127,-127 }, +}; + +const ubit_t gsm0503_ahs_ic_ubit[4][4] = { + { 0,0,0,0 }, + { 1,0,0,1 }, + { 1,1,1,0 }, + { 0,1,1,1 }, +}; + +const sbit_t gsm0503_ahs_ic_sbit[4][4] = { + { 127, 127, 127, 127 }, + { -127, 127, 127,-127 }, + { -127,-127,-127, 127 }, + { 127,-127,-127,-127 }, +}; + +const uint8_t gsm0503_tch_hr_interleaving[228][2] = { + { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 }, + { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 }, + { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 }, + { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 }, + { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 }, + { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 }, + { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 }, + { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 }, + { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 }, + { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 }, + { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 }, + { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 }, + { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 }, + { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 }, + { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 }, + { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 }, + { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 }, + { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 }, + { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 }, + { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 }, + { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 }, + { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 }, + { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 }, + { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 }, + { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 }, + { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 }, + { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 }, + { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 }, + { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 }, + { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 }, + { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 }, + { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 }, + { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 }, + { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 }, + { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 }, + { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 }, + { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 }, + { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 }, +}; + +/* + * 3GPP TS 05.03 5.1.9.1.2 "USF precoding" + */ +const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = { + { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, }, + { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, }, + { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, }, + { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, }, + { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, }, + { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, }, + { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, }, + { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, }, +}; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index dc8559f..1bde75d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -71,8 +71,12 @@ gsm0502_calc_paging_group; gsm0503_xcch; +gsm0503_rach; +gsm0503_sch; gsm0503_cs2; gsm0503_cs3; +gsm0503_tch_fr; +gsm0503_tch_hr; gsm0503_tch_afs_12_2; gsm0503_tch_afs_10_2; gsm0503_tch_afs_7_95; @@ -81,6 +85,124 @@ gsm0503_tch_afs_5_9; gsm0503_tch_afs_5_15; gsm0503_tch_afs_4_75; +gsm0503_tch_ahs_7_95; +gsm0503_tch_ahs_7_4; +gsm0503_tch_ahs_6_7; +gsm0503_tch_ahs_5_9; +gsm0503_tch_ahs_5_15; +gsm0503_tch_ahs_4_75; +gsm0503_pdtch_hl_hn_ubit; +gsm0503_pdtch_edge_hl_hn_ubit; +gsm0503_pdtch_hl_hn_sbit; +gsm0503_pdtch_edge_hl_hn_sbit; +gsm0503_usf2six; +gsm0503_usf2twelve_ubit; +gsm0503_usf2twelve_sbit; +gsm0503_puncture_cs2; +gsm0503_puncture_cs3; +gsm0503_puncture_mcs1_dl_hdr; +gsm0503_puncture_mcs1_ul_hdr; +gsm0503_puncture_mcs1_p1; +gsm0503_puncture_mcs1_p2; +gsm0503_puncture_mcs2_p1; +gsm0503_puncture_mcs2_p2; +gsm0503_puncture_mcs3_p1; +gsm0503_puncture_mcs3_p2; +gsm0503_puncture_mcs3_p3; +gsm0503_puncture_mcs4_p1; +gsm0503_puncture_mcs4_p2; +gsm0503_puncture_mcs4_p3; +gsm0503_puncture_mcs5_p1; +gsm0503_puncture_mcs5_p2; +gsm0503_puncture_mcs6_p1; +gsm0503_puncture_mcs6_p2; +gsm0503_puncture_mcs7_dl_hdr; +gsm0503_puncture_mcs7_ul_hdr; +gsm0503_puncture_mcs7_p1; +gsm0503_puncture_mcs7_p2; +gsm0503_puncture_mcs7_p3; +gsm0503_puncture_mcs8_p1; +gsm0503_puncture_mcs8_p2; +gsm0503_puncture_mcs8_p3; +gsm0503_puncture_mcs9_p1; +gsm0503_puncture_mcs9_p2; +gsm0503_puncture_mcs9_p3; +gsm0503_interleave_mcs5; +gsm0503_gsm_fr_map; +gsm0503_gsm_efr_protected_bits; +gsm0503_afs_ic_ubit; +gsm0503_afs_ic_sbit; +gsm0503_ahs_ic_ubit; +gsm0503_ahs_ic_sbit; +gsm0503_tch_hr_interleaving; +gsm0503_mcs5_usf_precode_table; + +gsm0503_xcch_deinterleave; +gsm0503_xcch_interleave; +gsm0503_tch_fr_deinterleave; +gsm0503_tch_fr_interleave; +gsm0503_tch_hr_deinterleave; +gsm0503_tch_hr_interleave; +gsm0503_mcs1_ul_interleave; +gsm0503_mcs1_ul_deinterleave; +gsm0503_mcs1_dl_interleave; +gsm0503_mcs1_dl_deinterleave; +gsm0503_mcs5_ul_interleave; +gsm0503_mcs5_ul_deinterleave; +gsm0503_mcs5_dl_interleave; +gsm0503_mcs5_dl_deinterleave; +gsm0503_mcs7_ul_interleave; +gsm0503_mcs7_ul_deinterleave; +gsm0503_mcs7_dl_interleave; +gsm0503_mcs7_dl_deinterleave; +gsm0503_mcs8_ul_interleave; +gsm0503_mcs8_ul_deinterleave; +gsm0503_mcs8_dl_interleave; +gsm0503_mcs8_dl_deinterleave; + +gsm0503_xcch_burst_unmap; +gsm0503_xcch_burst_map; +gsm0503_tch_burst_unmap; +gsm0503_tch_burst_map; +gsm0503_mcs5_ul_burst_map; +gsm0503_mcs5_ul_burst_unmap; +gsm0503_mcs7_ul_burst_map; +gsm0503_mcs7_ul_burst_unmap; +gsm0503_mcs5_dl_burst_map; +gsm0503_mcs5_dl_burst_unmap; +gsm0503_mcs7_dl_burst_map; +gsm0503_mcs7_dl_burst_unmap; +gsm0503_mcs5_burst_swap; + +gsm0503_fire_crc40; +gsm0503_cs234_crc16; +gsm0503_mcs_crc8_hdr; +gsm0503_mcs_crc12; +gsm0503_rach_crc6; +gsm0503_sch_crc10; +gsm0503_tch_fr_crc3; +gsm0503_tch_efr_crc8; +gsm0503_amr_crc6; + +gsm0503_egprs_mcs; +gsm0503_xcch_decode; +gsm0503_xcch_encode; +gsm0503_pdtch_decode; +gsm0503_pdtch_egprs_decode; +gsm0503_pdtch_encode; +gsm0503_pdtch_egprs_encode; +gsm0503_tch_fr_decode; +gsm0503_tch_fr_encode; +gsm0503_tch_hr_decode; +gsm0503_tch_hr_encode; +gsm0503_tch_afs_decode; +gsm0503_tch_afs_encode; +gsm0503_tch_ahs_decode; +gsm0503_tch_ahs_encode; +gsm0503_rach_decode; +gsm0503_rach_encode; +gsm0503_sch_decode; +gsm0503_sch_encode; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..7aa5a3c 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -1,7 +1,6 @@ #!/usr/bin/python2 -mod_license = """ -/* +mod_license = """/* * Copyright (C) 2011-2016 Sylvain Munaut * Copyright (C) 2016 sysmocom s.f.m.c. GmbH * @@ -27,7 +26,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, + name = "call-me", description = False, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +50,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -63,8 +68,13 @@ def _state_mask(self): return (1 << (self.k - 1)) - 1 + def combine(self, src, sel, nb): + x = src & sel + fn_xor = lambda x, y: x ^ y + return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) + def next_state(self, state, bit): - nb = combine( + nb = self.combine( (state << 1) | bit, self.poly_divider, self.k, @@ -85,9 +95,10 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -104,9 +115,9 @@ for p_n, p_d in self.polys: if self.recursive and p_d == 1: # Systematic output are replaced when in 'termination' mode - o = combine(src, self.poly_divider, self.k) + o = self.combine(src, self.poly_divider, self.k) else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -121,61 +132,118 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" if len(self.puncture): - print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p - print >>fi, "};" + # Up to 12 numbers should be placed per line + counter = 0 - print >>fi, "\n/* %s */" % self.description - print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, \ + "\nstatic const int %s_puncture[] = {" % self.name + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n};\n") + + # Write description as a multiline comment + if self.description: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Write a final definition + print >>fi, \ + "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k print >>fi, "\t.len = %d," % self.block_len print >>fi, "\t.next_output = %s_output," % self.name print >>fi, "\t.next_state = %s_state," % self.name + if self.recursive: print >>fi, "\t.next_term_output = %s_term_output," % self.name print >>fi, "\t.next_term_state = %s_term_state," % self.name + if len(self.puncture): print >>fi, "\t.puncture = %s_puncture," % self.name + print >>fi, "};" poly = lambda *args: sum([(1 << x) for x in args]) - -def combine(src, sel, nb): - x = src & sel - fn_xor = lambda x, y: x ^ y - return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) # Polynomials according to 3GPP TS 05.03 Annex B G0 = poly(0, 3, 4) @@ -188,307 +256,487 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # RACH definition + ConvolutionalCode( + 14, + CCH_poly, + name = "rach", + description = ["RACH convolutional code"] + ), -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # SCH definition + ConvolutionalCode( + 35, + CCH_poly, + name = "sch", + description = ["SCH convolutional code"] + ), -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), + + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), + + # TCH_FR definition + ConvolutionalCode( + 185, + CCH_poly, + name = "tch_fr", + description = ["TCH/F convolutional code"] + ), + + # TCH_HR definition + ConvolutionalCode( + 98, + [ + ( G4, 1 ), + ( G5, 1 ), + ( G6, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, + 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, + 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214, + 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250, + 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295, + 298, 301, 304, 307, 310, -1, + ], + name = "tch_hr", + description = ["TCH/H convolutional code"] + ), + + # TCH_AHS_7_95 definition + ConvolutionalCode( + 129, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43, + 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95, + 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151, + 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191, + 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221, + 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251, + 255, 257, 259, 261, 263, 265, -1, + ], + name = "tch_ahs_7_95", + description = ["TCH/AHS 7.95 kbits convolutional code"] + ), + + # TCH_AHS_7_4 definition + ConvolutionalCode( + 126, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55, + 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119, + 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, + 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, + 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251, + 253, 255, 257, 259, -1, + ], + name = "tch_ahs_7_4", + description = ["TCH/AHS 7.4 kbits convolutional code"] + ), + + # TCH_AHS_6_7 definition + ConvolutionalCode( + 116, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, + 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189, + 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231, + 233, 235, 237, 239, -1, + ], + name = "tch_ahs_6_7", + description = ["TCH/AHS 6.7 kbits convolutional code"] + ), + + # TCH_AHS_5_9 definition + ConvolutionalCode( + 108, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211, + 215, 219, 221, 223, -1, + ], + name = "tch_ahs_5_9", + description = ["TCH/AHS 5.9 kbits convolutional code"] + ), + + # TCH_AHS_5_15 definition + ConvolutionalCode( + 97, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33, + 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93, + 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159, + 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, + 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, + 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261, + 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289, + 291, 294, 295, 297, 298, 300, 301, -1, + ], + name = "tch_ahs_5_15", + description = ["TCH/AHS 5.15 kbits convolutional code"] + ), + + # TCH_AHS_4_75 definition + ConvolutionalCode( + 89, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34, + 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, + 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166, + 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, + 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256, + 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283, + 284, -1, + ], + name = "tch_ahs_4_75", + description = ["TCH/AHS 4.75 kbits convolutional code"] + ), +] + +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Mon Sep 5 16:32:18 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 5 Sep 2016 16:32:18 +0000 Subject: [PATCH] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/816 to look at the new patch set (#2). gsm0503: migrate transcoding routines from OsmoBTS The GSM 05.03 transcoding routines are becoming increasingly popular, and some projects (such as GR-GSM and OsmocomBB) also require transcoding capabilities implemented within the libosmocore. Moreover, it would be beeter to clean up the OsmoBTS source code, sharing this code. Currently there are the following data types supported: - xCCH - PDTCH - PDTCH (EDGE) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Also, the conv_gen.py was updated, and now writes a single file. The EDGE MCS convolutional codes are migrated 'as is', i.e. already in generated state. Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a --- M .gitignore M include/osmocom/gsm/gsm0503.h A include/osmocom/gsm/gsm0503_coding.h A include/osmocom/gsm/gsm0503_interleaving.h A include/osmocom/gsm/gsm0503_mapping.h A include/osmocom/gsm/gsm0503_parity.h A include/osmocom/gsm/gsm0503_tables.h M src/gsm/Makefile.am A src/gsm/gsm0503_coding.c A src/gsm/gsm0503_conv_edge.c A src/gsm/gsm0503_interleaving.c A src/gsm/gsm0503_mapping.c A src/gsm/gsm0503_parity.c A src/gsm/gsm0503_tables.c M src/gsm/libosmogsm.map M utils/conv_gen.py 16 files changed, 6,752 insertions(+), 327 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/16/816/2 diff --git a/.gitignore b/.gitignore index 5165364..dd9c61b 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ doc/*.tag src/crc*gen.c +src/gsm/gsm6*.c src/gsm/conv*gen.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index cf1c976..3fda4ce 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -26,7 +26,7 @@ #include -/*! \file conv_gen.h +/*! \file gsm0503.h * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03 */ @@ -36,10 +36,26 @@ */ extern const struct osmo_conv_code gsm0503_xcch; +/*! \brief structure describing convolutional code RACH + */ +extern const struct osmo_conv_code gsm0503_rach; + +/*! \brief structure describing convolutional code SCH + */ +extern const struct osmo_conv_code gsm0503_sch; + /*! \brief structures describing convolutional codes CS2/3 */ extern const struct osmo_conv_code gsm0503_cs2; extern const struct osmo_conv_code gsm0503_cs3; + +/*! \brief structure describing convolutional code TCH/FR + */ +extern const struct osmo_conv_code gsm0503_tch_fr; + +/*! \brief structure describing convolutional code TCH/HR + */ +extern const struct osmo_conv_code gsm0503_tch_hr; /*! \brief structure describing convolutional code TCH/AFS 12.2 */ @@ -72,3 +88,87 @@ /*! \brief structure describing convolutional code TCH/AFS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_afs_4_75; + +/*! \brief structure describing convolutional code TCH/AHS 7.95 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_95; + +/*! \brief structure describing convolutional code TCH/AHS 7.4 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_4; + +/*! \brief structure describing convolutional code TCH/AHS 6.7 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_6_7; + +/*! \brief structure describing convolutional code TCH/AHS 5.9 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_9; + +/*! \brief structure describing convolutional code TCH/AHS 5.15 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_15; + +/*! \brief structure describing convolutional code TCH/AHS 4.75 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; + +/*! \brief structure describing convolutional code EDGE MCS1 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 + */ +extern const struct osmo_conv_code gsm0503_mcs1; + +/*! \brief structure describing convolutional code EDGE MCS2 + */ +extern const struct osmo_conv_code gsm0503_mcs2; + +/*! \brief structure describing convolutional code EDGE MCS3 + */ +extern const struct osmo_conv_code gsm0503_mcs3; + +/*! \brief structure describing convolutional code EDGE MCS4 + */ +extern const struct osmo_conv_code gsm0503_mcs4; + +/*! \brief structure describing convolutional code EDGE MCS5 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 + */ +extern const struct osmo_conv_code gsm0503_mcs5; + +/*! \brief structure describing convolutional code EDGE MCS6 + */ +extern const struct osmo_conv_code gsm0503_mcs6; + +/*! \brief structure describing convolutional code EDGE MCS7 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 + */ +extern const struct osmo_conv_code gsm0503_mcs7; + +/*! \brief structure describing convolutional code EDGE MCS8 + */ +extern const struct osmo_conv_code gsm0503_mcs8; + +/*! \brief structure describing convolutional code EDGE MCS9 + */ +extern const struct osmo_conv_code gsm0503_mcs9; diff --git a/include/osmocom/gsm/gsm0503_coding.h b/include/osmocom/gsm/gsm0503_coding.h new file mode 100644 index 0000000..76f6b7a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_coding.h @@ -0,0 +1,85 @@ +/* + * GSM 05.03 transcoding routines + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +#define GSM0503_GPRS_BURSTS_NBITS (116 * 4) +#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4) + +struct osmo_conv_code; + +enum gsm0503_egprs_mcs { + EGPRS_MCS0, + EGPRS_MCS1, + EGPRS_MCS2, + EGPRS_MCS3, + EGPRS_MCS4, + EGPRS_MCS5, + EGPRS_MCS6, + EGPRS_MCS7, + EGPRS_MCS8, + EGPRS_MCS9, + EGPRS_NUM_MCS, +}; + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len); +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, uint8_t *l2_data, + uint8_t l2_len); +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, + uint16_t nbits, uint8_t *usf_p, int *n_errors, int *n_bits_total); + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int net_order); +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order, + int efr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len); +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total); + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr); +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr); +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic); +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic); + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info); +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst); diff --git a/include/osmocom/gsm/gsm0503_interleaving.h b/include/osmocom/gsm/gsm0503_interleaving.h new file mode 100644 index 0000000..3f477cc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_interleaving.h @@ -0,0 +1,72 @@ +/* + * GSM 05.03 interleaving + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); diff --git a/include/osmocom/gsm/gsm0503_mapping.h b/include/osmocom/gsm/gsm0503_mapping.h new file mode 100644 index 0000000..74a7b83 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_mapping.h @@ -0,0 +1,55 @@ +/* + * GSM 05.03 mapping + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn); +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn); + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd); +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd); + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs5_burst_swap(sbit_t *eB); diff --git a/include/osmocom/gsm/gsm0503_parity.h b/include/osmocom/gsm/gsm0503_parity.h new file mode 100644 index 0000000..fa8bacc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_parity.h @@ -0,0 +1,35 @@ +/* + * GSM 05.03 parity + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +const struct osmo_crc64gen_code gsm0503_fire_crc40; +const struct osmo_crc16gen_code gsm0503_cs234_crc16; +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr; +const struct osmo_crc16gen_code gsm0503_mcs_crc12; +const struct osmo_crc8gen_code gsm0503_rach_crc6; +const struct osmo_crc16gen_code gsm0503_sch_crc10; +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3; +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8; +const struct osmo_crc8gen_code gsm0503_amr_crc6; diff --git a/include/osmocom/gsm/gsm0503_tables.h b/include/osmocom/gsm/gsm0503_tables.h new file mode 100644 index 0000000..dbabfb7 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_tables.h @@ -0,0 +1,71 @@ +/* + * GSM 05.03 tables + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; +extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8]; +extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8]; +extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8]; +extern const ubit_t gsm0503_usf2six[8][6]; +extern const ubit_t gsm0503_usf2twelve_ubit[8][12]; +extern const sbit_t gsm0503_usf2twelve_sbit[8][12]; +extern const uint8_t gsm0503_puncture_cs2[588]; +extern const uint8_t gsm0503_puncture_cs3[676]; +extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108]; +extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117]; +extern const uint8_t gsm0503_puncture_mcs1_p1[588]; +extern const uint8_t gsm0503_puncture_mcs1_p2[588]; +extern const uint8_t gsm0503_puncture_mcs2_p1[732]; +extern const uint8_t gsm0503_puncture_mcs2_p2[732]; +extern const uint8_t gsm0503_puncture_mcs3_p1[948]; +extern const uint8_t gsm0503_puncture_mcs3_p2[948]; +extern const uint8_t gsm0503_puncture_mcs3_p3[948]; +extern const uint8_t gsm0503_puncture_mcs4_p1[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p2[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p3[1116]; +extern const uint8_t gsm0503_puncture_mcs5_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs5_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs6_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs6_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135]; +extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162]; +extern const uint8_t gsm0503_puncture_mcs7_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p3[1404]; +extern const uint8_t gsm0503_puncture_mcs8_p1[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p2[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p3[1692]; +extern const uint8_t gsm0503_puncture_mcs9_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p3[1836]; +extern const uint16_t gsm0503_interleave_mcs5[1248]; +extern const uint8_t gsm0503_gsm_fr_map[76]; +extern const uint8_t gsm0503_gsm_efr_protected_bits[65]; +extern const ubit_t gsm0503_afs_ic_ubit[4][8]; +extern const sbit_t gsm0503_afs_ic_sbit[4][8]; +extern const ubit_t gsm0503_ahs_ic_ubit[4][4]; +extern const sbit_t gsm0503_ahs_ic_sbit[4][4]; +extern const uint8_t gsm0503_tch_hr_interleaving[228][2]; +extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36]; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..13c08d6 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,16 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ + gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ + gsm0503_conv_edge.c gsm0503_tables.c \ + gsm0503_parity.c gsm0503_interleaving.c \ + gsm0503_mapping.c gsm0503_coding.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gprs_gea.c + libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +37,18 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: $(AM_V_GEN)python2 ../../utils/conv_gen.py + +# Some dependencies from libosmocodec +gsm610.c: + $(AM_V_GEN)cp ../codec/gsm610.c ./ + +gsm620.c: + $(AM_V_GEN)cp ../codec/gsm620.c ./ + +gsm660.c: + $(AM_V_GEN)cp ../codec/gsm660.c ./ + +CLEANFILES = gsm0503_conv.c gsm610.c gsm620.c gsm660.c diff --git a/src/gsm/gsm0503_coding.c b/src/gsm/gsm0503_coding.c new file mode 100644 index 0000000..49cbee7 --- /dev/null +++ b/src/gsm/gsm0503_coding.c @@ -0,0 +1,2694 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * EGPRS coding limits + */ + +/* Max header size with parity bits */ +#define EGPRS_HDR_UPP_MAX 54 + +/* Max encoded header size */ +#define EGPRS_HDR_C_MAX 162 + +/* Max punctured header size */ +#define EGPRS_HDR_HC_MAX 160 + +/* Max data block size with parity bits */ +#define EGPRS_DATA_U_MAX 612 + +/* Max encoded data block size */ +#define EGPRS_DATA_C_MAX 1836 + +/* Max single block punctured data size */ +#define EGPRS_DATA_DC_MAX 1248 + +/* Dual block punctured data size */ +#define EGPRS_DATA_C1 612 +#define EGPRS_DATA_C2 EGPRS_DATA_C1 + +/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ +#define GSM_FR_BYTES 33 +/* TS 101318 Chapter 5.2: 112 bits, no sig */ +#define GSM_HR_BYTES 14 +/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ +#define GSM_EFR_BYTES 31 + +struct gsm0503_mcs_code { + uint8_t mcs; + uint8_t usf_len; + + /* Header coding */ + uint8_t hdr_len; + uint8_t hdr_code_len; + uint8_t hdr_punc_len; + const struct osmo_conv_code *hdr_conv; + const uint8_t *hdr_punc; + + /* Data coding */ + uint16_t data_len; + uint16_t data_code_len; + uint16_t data_punc_len; + const struct osmo_conv_code *data_conv; + const uint8_t *data_punc[3]; +}; + +/* + * EGPRS UL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_ul_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +/* + * EGPRS DL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_dl_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +static int osmo_conv_decode_ber(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output, + int *n_errors, int *n_bits_total) +{ + int res, i, coded_len; + ubit_t recoded[EGPRS_DATA_C_MAX]; + + res = osmo_conv_decode(code, input, output); + + if (n_bits_total || n_errors) { + coded_len = osmo_conv_encode(code, output, recoded); + OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len); + } + + /* Count bit errors */ + if (n_errors) { + *n_errors = 0; + for (i = 0; i < coded_len; i++) { + if (! ((recoded[i] && input[i] < 0) || + (!recoded[i] && input[i] > 0)) ) + *n_errors += 1; + } + } + + if (n_bits_total) + *n_bits_total = coded_len; + + return res; +} + + +static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB, + int *n_errors, int *n_bits_total) +{ + ubit_t conv[224]; + int rv; + + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 0; +} + +static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data) +{ + ubit_t conv[224]; + + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + return 0; +} + + +/* + * GSM xCCH block transcoding + */ + +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[456]; + int i; + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL); + + gsm0503_xcch_deinterleave(cB, iB); + + return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total); +} + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data) +{ + ubit_t iB[456], cB[456], hl = 1, hn = 1; + int i; + + _xcch_encode_cB(cB, l2_data); + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn); + + return 0; +} + +/* + * EGPRS PDTCH UL block decoding + */ + +/* + * Type 3 - MCS-1,2,3,4 + * Unmapping and deinterleaving + */ +static int egprs_type3_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t iB[456], q[8]; + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + q + i * 2, q + i * 2 + 1); + } + + gsm0503_mcs1_ul_deinterleave(hc, dc, iB); + + return 0; +} + +/* + * Type 2 - MCS-5,6 + * Unmapping and deinterleaving + */ +static int egprs_type2_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_DC_MAX]; + + for (i=0; i<4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs5_ul_burst_unmap(di, burst, hi, i); + } + + gsm0503_mcs5_ul_deinterleave(hc, dc, hi, di); + + return 0; +} + +/* + * Type 1 - MCS-7,8,9 + * Unmapping and deinterleaving - Note that MCS-7 interleaver is unique + */ +static int egprs_type1_unmap(const sbit_t *bursts, sbit_t *hc, + sbit_t *c1, sbit_t *c2, int msc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_C1 * 2]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs7_ul_burst_unmap(di, burst, hi, i); + } + + if (msc == EGPRS_MCS7) + gsm0503_mcs7_ul_deinterleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_ul_deinterleave(hc, c1, c2, hi, di); + + return 0; +} + +union gprs_rlc_ul_hdr_egprs { + struct gprs_rlc_ul_header_egprs_1 type1; + struct gprs_rlc_ul_header_egprs_2 type2; + struct gprs_rlc_ul_header_egprs_3 type3; +}; + +/* + * Decode EGPRS UL header section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + */ +static int _egprs_decode_hdr(const sbit_t *hc, int mcs, + union gprs_rlc_ul_hdr_egprs *hdr) +{ + sbit_t C[EGPRS_HDR_C_MAX]; + ubit_t upp[EGPRS_HDR_UPP_MAX]; + int i, j, rc; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_ul_codes[mcs]; + + /* Skip depuncturing on MCS-5,6 header */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(C, hc, code->hdr_code_len); + goto hdr_conv_decode; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + i = code->hdr_code_len - 1; + j = code->hdr_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->hdr_punc[i]) + C[i] = hc[j--]; + else + C[i] = 0; + } + +hdr_conv_decode: + osmo_conv_decode_ber(code->hdr_conv, C, upp, NULL, NULL); + rc = osmo_crc8gen_check_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + if (rc) + return -1; + + osmo_ubit2pbit_ext((pbit_t *) hdr, 0, upp, 0, code->hdr_len, 1); + + return 0; +} + +/* + * Blind MCS header decoding based on burst length and CRC validation. + * Ignore 'q' value coding indentification. This approach provides + * the strongest chance of header recovery. + */ +static int egprs_decode_hdr(union gprs_rlc_ul_hdr_egprs *hdr, + const sbit_t *bursts, uint16_t nbits) +{ + int rc; + sbit_t hc[EGPRS_HDR_HC_MAX]; + + if (nbits == GSM0503_GPRS_BURSTS_NBITS) { + /* MCS-1,2,3,4 */ + egprs_type3_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS1, hdr); + if (!rc) + return EGPRS_HDR_TYPE3; + } else if (nbits == GSM0503_EGPRS_BURSTS_NBITS) { + /* MCS-5,6 */ + egprs_type2_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS5, hdr); + if (!rc) + return EGPRS_HDR_TYPE2; + + /* MCS-7,8,9 */ + egprs_type1_unmap(bursts, hc, NULL, NULL, EGPRS_MCS7); + rc = _egprs_decode_hdr(hc, EGPRS_MCS7, hdr); + if (!rc) + return EGPRS_HDR_TYPE1; + } + + return -1; +} + +/* + * Parse EGPRS UL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_ul_cps(struct egprs_cps *cps, + union gprs_rlc_ul_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = (hdr->type2.cps_lo << 2) | hdr->type2.cps_hi; + break; + case EGPRS_HDR_TYPE3: + bits = (hdr->type3.cps_lo << 2) | hdr->type3.cps_hi; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +#define NUM_BYTES(N) ((N + 8 - 1) / 8) + +/* + * Decode EGPRS UL data section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + * 4. Block combining (MCS-7,8,9 only) + */ +static int egprs_decode_data(uint8_t *l2_data, sbit_t *c, + int mcs, int p, int blk, + int *n_errors, int *n_bits_total) +{ + ubit_t u[EGPRS_DATA_U_MAX]; + sbit_t C[EGPRS_DATA_C_MAX]; + + int i, j, rc, data_len; + struct gsm0503_mcs_code *code; + + if (blk && mcs < EGPRS_MCS7) { + /* Invalid MCS-X block state */ + return -1; + } + + code = &gsm0503_mcs_ul_codes[mcs]; + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + /* + * MCS-1,6 - single block processing + * MCS-7,9 - dual block processing + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + i = code->data_code_len - 1; + j = code->data_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->data_punc[p][i]) + C[i] = c[j--]; + else + C[i] = 0; + } + + osmo_conv_decode_ber(code->data_conv, C, u, n_errors, n_bits_total); + rc = osmo_crc16gen_check_bits(&gsm0503_mcs_crc12, u, + data_len, u + data_len); + if (rc) + return -1; + + /* Offsets output pointer on the second block of Type 1 MCS */ + osmo_ubit2pbit_ext(l2_data, code->hdr_len + blk * data_len, + u, 0, data_len, 1); + + /* Return the number of bytes required for the bit message */ + return NUM_BYTES(code->hdr_len + code->data_len); +} + +/* + * Decode EGPRS UL message + * + * 1. Header section decoding + * 2. Extract CPS settings + * 3. Burst unmapping and deinterleaving + * 4. Data section decoding + */ +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, uint16_t nbits, + uint8_t *usf_p, int *n_errors, int *n_bits_total) +{ + sbit_t dc[EGPRS_DATA_DC_MAX]; + sbit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + int type, rc; + struct egprs_cps cps; + union gprs_rlc_ul_hdr_egprs *hdr; + + if ((nbits != GSM0503_GPRS_BURSTS_NBITS) && + (nbits != GSM0503_EGPRS_BURSTS_NBITS)) { + /* Invalid EGPRS bit length */ + return -1; + } + + hdr = (union gprs_rlc_ul_hdr_egprs *) l2_data; + type = egprs_decode_hdr(hdr, bursts, nbits); + if (egprs_parse_ul_cps(&cps, hdr, type) < 0) + return -1; + + switch (cps.mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + egprs_type3_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + egprs_type2_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + egprs_type1_unmap(bursts, NULL, c1, c2, cps.mcs); + break; + default: + /* Invalid MCS-X */ + return -1; + } + + /* Decode MCS-X block, where X = cps.mcs */ + if (cps.mcs < EGPRS_MCS7) { + rc = egprs_decode_data(l2_data, dc, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + } else { + /* MCS-7,8,9 block 1 */ + rc = egprs_decode_data(l2_data, c1, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + + /* MCS-7,8,9 block 2 */ + rc = egprs_decode_data(l2_data, c2, cps.mcs, cps.p[1], + 1, n_errors, n_bits_total); + if (rc < 0) + return -1; + } + + return rc; +} + +/* + * GSM PDTCH block transcoding + */ + +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[676], hl_hn[8]; + ubit_t conv[456]; + int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */ + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j])); + + if (i == 0 || k < best) { + best = k; + cs = i+1; + } + } + + gsm0503_xcch_deinterleave(cB, iB); + + switch (cs) { + case 1: + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 23; + case 2: + for (i = 587, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs2[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs2, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 271, conv + 3 + 271); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1); + + return 34; + case 3: + for (i = 675, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs3[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs3, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 315, conv + 3 + 315); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1); + + return 40; + case 4: + for (i = 12; i < 456; i++) + conv[i] = (cB[i] < 0) ? 1 : 0; + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 12; j++) + k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[9] = usf & 1; + conv[10] = (usf >> 1) & 1; + conv[11] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 9, 431, conv + 9 + 431); + if (rv) { + *n_bits_total = 456 - 12; + *n_errors = *n_bits_total; + return -1; + } + + *n_bits_total = 456 - 12; + *n_errors = 0; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1); + + return 54; + default: + *n_bits_total = 0; + *n_errors = 0; + break; + } + + return -1; +} + +/* + * EGPRS PDTCH UL block encoding + */ +static int egprs_type3_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + ubit_t iB[456]; + const ubit_t *hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + gsm0503_mcs1_dl_interleave(gsm0503_usf2six[usf], hc, dc, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return 0; +} + +static int egprs_type2_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_DC_MAX]; + + gsm0503_mcs5_dl_interleave(hc, dc, hi, di); + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs5_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_type1_map(ubit_t *bursts, ubit_t *hc, + ubit_t *c1, ubit_t *c2, int usf, int mcs) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_C1 * 2]; + + if (mcs == EGPRS_MCS7) + gsm0503_mcs7_dl_interleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_dl_interleave(hc, c1, c2, hi, di); + + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs7_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_encode_hdr(ubit_t *hc, uint8_t *l2_data, int mcs) +{ + int i, j; + ubit_t upp[EGPRS_HDR_UPP_MAX], C[EGPRS_HDR_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + osmo_pbit2ubit_ext(upp, 0, l2_data, code->usf_len, code->hdr_len, 1); + osmo_crc8gen_set_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + + osmo_conv_encode(code->hdr_conv, upp, C); + + /* MCS-5,6 header direct puncture instead of table */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(hc, C, code->hdr_code_len); + hc[99] = hc[98]; + return 0; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->hdr_code_len; i++) { + if (!code->hdr_punc[i]) + hc[j++] = C[i]; + } + + return 0; +} + +static int egprs_encode_data(ubit_t *c, uint8_t *l2_data, + int mcs, int p, int blk) +{ + int i, j, data_len; + ubit_t u[EGPRS_DATA_U_MAX], C[EGPRS_DATA_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + /* + * Dual block - MCS-7,8,9 + * Single block - MCS-1,2,3,4,5,6 + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + osmo_pbit2ubit_ext(u, 0, l2_data, + code->usf_len + code->hdr_len + blk * data_len, data_len, 1); + + osmo_crc16gen_set_bits(&gsm0503_mcs_crc12, u, data_len, u + data_len); + + osmo_conv_encode(code->data_conv, u, C); + + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->data_code_len; i++) { + if (!code->data_punc[p][i]) + c[j++] = C[i]; + } + + return 0; +} + +union gprs_rlc_dl_hdr_egprs { + struct gprs_rlc_dl_header_egprs_1 type1; + struct gprs_rlc_dl_header_egprs_2 type2; + struct gprs_rlc_dl_header_egprs_3 type3; +}; + +/* + * Parse EGPRS DL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_dl_cps(struct egprs_cps *cps, + union gprs_rlc_dl_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = hdr->type2.cps; + break; + case EGPRS_HDR_TYPE3: + bits = hdr->type3.cps; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * EGPRS DL message encoding + */ +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, + uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t hc[EGPRS_DATA_C_MAX], dc[EGPRS_DATA_DC_MAX]; + ubit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + uint8_t mcs; + struct egprs_cps cps; + union gprs_rlc_dl_hdr_egprs *hdr; + + switch (l2_len) { + case 27: + mcs = EGPRS_MCS1; + break; + case 33: + mcs = EGPRS_MCS2; + break; + case 42: + mcs = EGPRS_MCS3; + break; + case 49: + mcs = EGPRS_MCS4; + break; + case 60: + mcs = EGPRS_MCS5; + break; + case 78: + mcs = EGPRS_MCS6; + break; + case 118: + mcs = EGPRS_MCS7; + break; + case 142: + mcs = EGPRS_MCS8; + break; + case 154: + mcs = EGPRS_MCS9; + break; + default: + return -1; + } + + /* Read header for USF and puncturing matrix selection. */ + hdr = (union gprs_rlc_dl_hdr_egprs *) l2_data; + + switch (mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + /* Check for valid CPS and matching MCS to message size */ + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE3) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type3_map(bursts, hc, dc, hdr->type3.usf); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE2) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type2_map(bursts, hc, dc, hdr->type2.usf); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE1) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(c1, l2_data, mcs, cps.p[0], 0); + egprs_encode_data(c2, l2_data, mcs, cps.p[1], 1); + egprs_type1_map(bursts, hc, c1, c2, hdr->type1.usf, mcs); + break; + } + + return mcs >= EGPRS_MCS5 ? GSM0503_EGPRS_BURSTS_NBITS : + GSM0503_GPRS_BURSTS_NBITS; + +bad_header: + /* Invalid EGPRS MCS-X header */ + return -1; +} + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t iB[456], cB[676]; + const ubit_t *hl_hn; + ubit_t conv[334]; + int i, j, usf; + + switch (l2_len) { + case 23: + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[0]; + + break; + case 34: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 271, conv + 3 + 271); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs2, conv, cB); + + for (i = 0, j = 0; i < 588; i++) + if (!gsm0503_puncture_cs2[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[1]; + + break; + case 40: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 315, conv + 3 + 315); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs3, conv, cB); + + for (i = 0, j = 0; i < 676; i++) + if (!gsm0503_puncture_cs3[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[2]; + + break; + case 54: + osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9, + 431, cB + 9 + 431); + + memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + break; + default: + return -1; + } + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return GSM0503_GPRS_BURSTS_NBITS; +} + + +/* + * GSM TCH/F FR/EFR transcoding + */ + +static void tch_fr_reassemble(uint8_t *tch_data, + ubit_t *b_bits, int net_order) +{ + int i, j, k, l, o; + + tch_data[0] = 0xd << 4; + memset(tch_data + 1, 0, 32); + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); + + return; + } + + /* reassemble d-bits */ + i = 0; /* counts bits */ + j = 4; /* counts output bits */ + k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset input bits */ + while (i < 260) { + tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7))); + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l]-1; + } + i++; + j++; + } +} + +static void tch_fr_disassemble(ubit_t *b_bits, + uint8_t *tch_data, int net_order) +{ + int i, j, k, l, o; + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + + return; + } + + i = 0; /* counts bits */ + j = 4; /* counts input bits */ + k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset output bits */ + while (i < 260) { + b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l] - 1; + } + i++; + j++; + } +} + +static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0x00; /* F = 0, FT = 000 */ + memset(tch_data + 1, 0, 14); + + for (i = 0, j = 8; i < 112; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 8; i < 112; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0xc << 4; + memset(tch_data + 1, 0, 30); + + for (i = 0, j = 4; i < 244; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 4; i < 244; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len) +{ + int i, j; + + memset(tch_data, 0, (len + 7) >> 3); + + for (i = 0, j = 0; i < len; i++, j++) + tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7))); +} + +static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len) +{ + int i, j; + + for (i = 0, j = 0; i < len; i++, j++) + d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm610_bitorder[i]] = d_bits[i]; +} + +static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm610_bitorder[i]]; +} + +static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + const uint16_t *map; + + if (!b_bits[34] && !b_bits[35]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + d_bits[i] = b_bits[map[i]]; +} + +static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm660_bitorder[i]] = d_bits[i]; +} + +static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm660_bitorder[i]]; +} + +static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 65; i++) + b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1]; +} + +static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + int i; + + for (i = 0; i < 91; i++) { + d[i << 1] = u[i]; + d[(i << 1) + 1] = u[184 - i]; + } + + for (i = 0; i < 3; i++) + p[i] = u[91 + i]; +} + +static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + int i; + + for (i = 0; i < 91; i++) { + u[i] = d[i << 1]; + u[184 - i] = d[(i << 1) + 1]; + } + + for (i = 0; i < 3; i++) + u[91 + i] = p[i]; +} + +static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + memcpy(d, u, 95); + memcpy(p, u + 95, 3); +} + +static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + memcpy(u, d, 95); + memcpy(u + 95, p, 3); +} + +static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p) +{ + memcpy(w, s, 71); + w[71] = w[72] = s[69]; + memcpy(w + 73, s + 71, 50); + w[123] = w[124] = s[119]; + memcpy(w + 125, s + 121, 53); + w[178] = w[179] = s[172]; + memcpy(w + 180, s + 174, 50); + w[230] = w[231] = s[222]; + memcpy(w + 232, s + 224, 20); + memcpy(w + 252, p, 8); +} + +static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w) +{ + int sum; + + memcpy(s, w, 71); + sum = s[69] + w[71] + w[72]; + s[69] = (sum > 2); + memcpy(s + 71, w + 73, 50); + sum = s[119] + w[123] + w[124]; + s[119] = (sum > 2); + memcpy(s + 121, w + 125, 53); + sum = s[172] + w[178] + w[179]; + s[172] = (sum > 2); + memcpy(s + 174, w + 180, 50); + sum = s[220] + w[230] + w[231]; + s[222] = (sum > 2); + memcpy(s + 224, w + 232, 20); + memcpy(p, w + 252, 8); +} + +static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot) +{ + memcpy(u, d, prot); + memcpy(u + prot, p, 6); + memcpy(u + prot + 6, d + prot, len - prot); +} + +static void tch_amr_unmerge(ubit_t *d, ubit_t *p, + ubit_t *u, int len, int prot) +{ + memcpy(d, u, prot); + memcpy(p, u+prot, 6); + memcpy(d + prot, u + prot + 6, len - prot); +} + +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, + int net_order, int efr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[185], s[244], w[260], b[65], d[260], p[8]; + int i, rv, len, steal = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return 23; + } + + osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total); + + tch_fr_unreorder(d, p, conv); + + for (i = 0; i < 78; i++) + d[i + 182] = (cB[i + 378] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p); + if (rv) { + /* Error checking CRC8 for the FR part of an EFR/FR frame */ + return -1; + } + + if (efr) { + tch_efr_d_to_w(w, d); + + tch_efr_unreorder(s, p, w); + + tch_efr_protected(s, b); + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p); + if (rv) { + /* Error checking CRC8 for the EFR part of an EFR frame */ + return -1; + } + + tch_efr_reassemble(tch_data, s); + + len = GSM_EFR_BYTES; + } else { + tch_fr_d_to_b(w, d); + + tch_fr_reassemble(tch_data, w, net_order); + + len = GSM_FR_BYTES; + } + + return len; +} + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, + int len, int net_order) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[185], w[260], b[65], s[244], d[260], p[8]; + int i; + + switch (len) { + case GSM_EFR_BYTES: /* TCH EFR */ + + tch_efr_disassemble(s, tch_data); + + tch_efr_protected(s, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p); + + tch_efr_reorder(w, s, p); + + tch_efr_w_to_d(d, w); + + goto coding_efr_fr; + case GSM_FR_BYTES: /* TCH FR */ + tch_fr_disassemble(w, tch_data, net_order); + + tch_fr_b_to_d(d, w); + +coding_efr_fr: + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p); + + tch_fr_reorder(conv, d, p); + + memcpy(cB + 378, d + 182, 78); + + osmo_conv_encode(&gsm0503_tch_fr, conv, cB); + + h = 0; + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + break; + default: + return -1; + } + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; +} + +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i, rv, steal = 0; + + /* Only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* If we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total); + + tch_hr_unreorder(d, p, conv); + + for (i = 0; i < 17; i++) + d[i + 95] = (cB[i + 211] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + if (rv) { + /* Error checking CRC8 for an HR frame */ + return -1; + } + + tch_hr_d_to_b(b, d); + + tch_hr_reassemble(tch_data, b); + + return 15; +} + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i; + + switch (len) { + case 15: /* TCH HR */ + tch_hr_disassemble(b, tch_data); + + tch_hr_b_to_d(d, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + + tch_hr_reorder(conv, d, p); + + osmo_conv_encode(&gsm0503_tch_hr, conv, cB); + + memcpy(cB + 211, d + 95, 17); + + h = 0; + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 1); + } + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i=0; i<6; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + for (i=2; i<4; i++) { + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + } + + break; + default: + return -1; + } + + return 0; +} + +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + *n_errors = 0; *n_bits_total = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 7: /* TCH/AFS12.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 244, 81); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p); + if (rv) { + /* Error checking CRC8 for an AMR 12.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 244); + + len = 31; + + break; + case 6: /* TCH/AFS10.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 204, 65); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p); + if (rv) { + /* Error checking CRC8 for an AMR 10.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 204); + + len = 26; + + break; + case 5: /* TCH/AFS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 159, 75); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AFS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 148, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AFS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 134, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AFS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 118, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AFS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 103, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AFS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 95, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 448; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + goto facch; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID is not in codec list! */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID is not in codec list! */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 7: /* TCH/AFS12.2 */ + if (len != 31) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 244); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p); + + tch_amr_merge(conv, d, p, 244, 81); + + osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8); + + break; + case 6: /* TCH/AFS10.2 */ + if (len != 26) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 204); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p); + + tch_amr_merge(conv, d, p, 204, 65); + + osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8); + + break; + case 5: /* TCH/AFS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p); + + tch_amr_merge(conv, d, p, 159, 75); + + osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8); + + break; + case 4: /* TCH/AFS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 148, 61); + + osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8); + + break; + case 3: /* TCH/AFS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 134, 55); + + osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8); + + break; + case 2: /* TCH/AFS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 118, 55); + + osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8); + + break; + case 1: /* TCH/AFS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 103, 49); + + osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8); + + break; + case 0: /* TCH/AFS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 95, 39); + + osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 8); + +facch: + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + + /* only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* if we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 4; j++) + k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 5: /* TCH/AHS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 123, 67); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + for (i = 0; i < 36; i++) + d[i + 123] = (cB[i + 192] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AHS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 120, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + for (i = 0; i < 28; i++) + d[i + 120] = (cB[i + 200] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AHS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 110, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + for (i = 0; i < 24; i++) + d[i + 110] = (cB[i + 204] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AHS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 102, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + for (i = 0; i < 16; i++) + d[i + 102] = (cB[i + 212] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AHS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 91, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 91] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AHS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 83, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 83] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 159; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 6; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], + &h, i >> 2); + for (i = 2; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + + return 0; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID %d not in codec list */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID %d not in codec list */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 5: /* TCH/AHS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p); + + tch_amr_merge(conv, d, p, 123, 67); + + osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4); + + memcpy(cB + 192, d + 123, 36); + + break; + case 4: /* TCH/AHS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 120, 61); + + osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4); + + memcpy(cB + 200, d + 120, 28); + + break; + case 3: /* TCH/AHS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 110, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4); + + memcpy(cB + 204, d + 110, 24); + + break; + case 2: /* TCH/AHS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 102, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4); + + memcpy(cB + 212, d + 102, 16); + + break; + case 1: /* TCH/AHS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 91, 49); + + osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4); + + memcpy(cB + 216, d + 91, 12); + + break; + case 0: /* TCH/AHS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 83, 39); + + osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4); + + memcpy(cB + 216, d + 83, 12); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 4); + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1); + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +/* + * GSM RACH transcoding + */ + +/* + * GSM RACH apply BSIC to parity + * + * p(j) = p(j) xor b(j) j = 0, ..., 5 + * b(0) = MSB of PLMN colour code + * b(5) = LSB of BS colour code + */ + +static int rach_apply_bsic(ubit_t *d, uint8_t bsic) +{ + int i; + + /* Apply it */ + for (i = 0; i < 6; i++) + d[8 + i] ^= ((bsic >> (5 - i)) & 1); + + return 0; +} + +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic) +{ + ubit_t conv[14]; + int rv; + + osmo_conv_decode(&gsm0503_rach, burst, conv); + + rach_apply_bsic(conv, bsic); + + rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + if (rv) + return -1; + + osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1); + + return 0; +} + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic) +{ + ubit_t conv[14]; + + osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1); + + osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + + rach_apply_bsic(conv, bsic); + + osmo_conv_encode(&gsm0503_rach, conv, burst); + + return 0; +} + + +/* + * GSM SCH transcoding + */ + +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst) +{ + ubit_t conv[35]; + int rv; + + osmo_conv_decode(&gsm0503_sch, burst, conv); + + rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + if (rv) + return -1; + + osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1); + + return 0; +} + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info) +{ + ubit_t conv[35]; + + osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1); + + osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + + osmo_conv_encode(&gsm0503_sch, conv, burst); + + return 0; +} diff --git a/src/gsm/gsm0503_conv_edge.c b/src/gsm/gsm0503_conv_edge.c new file mode 100644 index 0000000..a542323 --- /dev/null +++ b/src/gsm/gsm0503_conv_edge.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2016 Tom Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +static const uint8_t conv_mcs_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, +}; + +static const uint8_t conv_mcs_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + + +const struct osmo_conv_code gsm0503_mcs1_dl_hdr = { + .N = 3, + .K = 7, + .len = 36, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1_ul_hdr = { + .N = 3, + .K = 7, + .len = 39, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1 = { + .N = 3, + .K = 7, + .len = 190, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs2 = { + .N = 3, + .K = 7, + .len = 238, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs3 = { + .N = 3, + .K = 7, + .len = 310, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs4 = { + .N = 3, + .K = 7, + .len = 366, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_dl_hdr = { + .N = 3, + .K = 7, + .len = 33, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_ul_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs6 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_dl_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_ul_hdr = { + .N = 3, + .K = 7, + .len = 54, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs8 = { + .N = 3, + .K = 7, + .len = 558, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs9 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; diff --git a/src/gsm/gsm0503_interleaving.c b/src/gsm/gsm0503_interleaving.c new file mode 100644 index 0000000..0c1b8a0 --- /dev/null +++ b/src/gsm/gsm0503_interleaving.c @@ -0,0 +1,574 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include +#include + +/* + * GSM xCCH interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 4 blocks of 114 bits: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 4) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (u) { + for (k=0; k<12; k++) + u[k] = c[k]; + } + + if (hc) { + for (k=12; k<80; k++) + hc[k - 12] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<12; k++) + c[k] = up[k]; + for (k=12; k<80; k++) + c[k] = hc[k - 12]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (hc) { + for (k=0; k<80; k++) + hc[k] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<80; k++) + c[k] = hc[k]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +/* + * GSM TCH FR/EFR/AFS interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 8 blocks of 114 bits, + * where even bits of the first 4 blocks and odd bits of the last 4 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 8) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +/* + * GSM TCH HR/AHS interleaving and burst mapping + * + * Interleaving: + * + * Given 288 coded input bits, form 4 blocks of 114 bits, + * where even bits of the first 2 blocks and odd bits of the last 2 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 227 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 2n + b + * j, b = table[k]; + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + iB[B * 114 + j] = cB[k]; + } +} + diff --git a/src/gsm/gsm0503_mapping.c b/src/gsm/gsm0503_mapping.c new file mode 100644 index 0000000..c2079b9 --- /dev/null +++ b/src/gsm/gsm0503_mapping.c @@ -0,0 +1,291 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn) +{ + memcpy(iB, eB, 57); + memcpy(iB+57, eB+59, 57); + + if (hl) + *hl = eB[57]; + + if (hn) + *hn = eB[58]; +} + +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn) +{ + memcpy(eB, iB, 57); + memcpy(eB+59, iB+57, 57); + + if (hl) + eB[57] = *hl; + if (hn) + eB[58] = *hn; +} + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (iB) { + for (i=odd; i<57; i+=2) + iB[i] = eB[i]; + for (i=58-odd; i<114; i+=2) + iB[i] = eB[i+2]; + } + + if (h) { + if (!odd) + *h = eB[58]; + else + *h = eB[57]; + } +} + +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (eB) { + for (i=odd; i<57; i+=2) + eB[i] = iB[i]; + for (i=58-odd; i<114; i+=2) + eB[i+2] = iB[i]; + } + + if (h) { + if (!odd) + eB[58] = *h; + else + eB[57] = *h; + } +} + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<168; j++) + eB[j] = hi[25*B+j-156]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<192; j++) + eB[j] = hi[25*B+j-167]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<168; j++) + hi[25*B+j-156] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<192; j++) + hi[25*B+j-167] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<174; j++) + eB[j] = hi[34*B+j-156]; + for (j=174; j<176; j++) + eB[j] = 0; + for (j=176; j<192; j++) + eB[j] = hi[34*B+j-158]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<174; j++) + hi[34*B+j-156] = eB[j]; + for (j=176; j<192; j++) + hi[34*B+j-158] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<168; j++) + eB[j] = hi[31*B+j-153]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<195; j++) + eB[j] = hi[31*B+j-164]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<168; j++) + hi[31*B+j-153] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<195; j++) + hi[31*B+j-164] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<174; j++) + eB[j] = hi[40*B+j-153]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<195; j++) + eB[j] = hi[40*B+j-155]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<174; j++) + hi[40*B+j-153] = eB[j]; + + for (j=176; j<195; j++) + hi[40*B+j-155] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs5_burst_swap(sbit_t *eB) +{ + sbit_t t[14]; + + t[0] = eB[155]; + t[1] = eB[158]; + t[2] = eB[161]; + t[3] = eB[164]; + t[4] = eB[167]; + t[5] = eB[170]; + t[6] = eB[173]; + t[7] = eB[195]; + t[8] = eB[196]; + t[9] = eB[198]; + t[10] = eB[199]; + t[11] = eB[201]; + t[12] = eB[202]; + t[13] = eB[204]; + + eB[155] = eB[142]; + eB[158] = eB[144]; + eB[161] = eB[145]; + eB[164] = eB[147]; + eB[167] = eB[148]; + eB[170] = eB[150]; + eB[173] = eB[151]; + eB[195] = eB[176]; + eB[196] = eB[179]; + eB[198] = eB[182]; + eB[199] = eB[185]; + eB[201] = eB[188]; + eB[202] = eB[191]; + eB[204] = eB[194]; + + eB[142] = t[0]; + eB[144] = t[1]; + eB[145] = t[2]; + eB[147] = t[3]; + eB[148] = t[4]; + eB[150] = t[5]; + eB[151] = t[6]; + eB[176] = t[7]; + eB[179] = t[8]; + eB[182] = t[9]; + eB[185] = t[10]; + eB[188] = t[11]; + eB[191] = t[12]; + eB[194] = t[13]; +} diff --git a/src/gsm/gsm0503_parity.c b/src/gsm/gsm0503_parity.c new file mode 100644 index 0000000..c9cfba4 --- /dev/null +++ b/src/gsm/gsm0503_parity.c @@ -0,0 +1,145 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +/* + * GSM (SACCH) parity (FIRE code) + * + * g(x) = (x^23 + 1)(x^17 + x^3 + 1) + * = x^40 + x^26 + x^23 + x^17 + x^3 + a1 + */ + +const struct osmo_crc64gen_code gsm0503_fire_crc40 = { + .bits = 40, + .poly = 0x0004820009ULL, + .init = 0x0000000000ULL, + .remainder = 0xffffffffffULL, +}; + + +/* + * GSM PDTCH CS-2, CS-3, CS-4 parity + * + * g(x) = x^16 + x^12 + x^5 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_cs234_crc16 = { + .bits = 16, + .poly = 0x1021, + .init = 0x0000, + .remainder = 0xffff, +}; + +/* + * EDGE MCS header parity + * + */ + +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = { + .bits = 8, + .poly = 0x49, + .init = 0x00, + .remainder = 0xff, +}; + +/* + * EDGE MCS data parity + * + */ + +const struct osmo_crc16gen_code gsm0503_mcs_crc12 = { + .bits = 12, + .poly = 0x0d31, + .init = 0x0000, + .remainder = 0x0fff, +}; + +/* + * GSM RACH parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_rach_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + + +/* + * GSM SCH parity + * + * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_sch_crc10 = { + .bits = 10, + .poly = 0x175, + .init = 0x000, + .remainder = 0x3ff, +}; + + +/* + * GSM TCH FR/HR/EFR parity + * + * g(x) = x^3 + x + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = { + .bits = 3, + .poly = 0x3, + .init = 0x0, + .remainder = 0x7, +}; + +/* + * GSM TCH EFR parity + * + * g(x) = x^8 + x^4 + x^3 + x^2 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = { + .bits = 8, + .poly = 0x1d, + .init = 0x00, + .remainder = 0x00, +}; + +/* + * GSM AMR parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_amr_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + diff --git a/src/gsm/gsm0503_tables.c b/src/gsm/gsm0503_tables.c new file mode 100644 index 0000000..95132b1 --- /dev/null +++ b/src/gsm/gsm0503_tables.c @@ -0,0 +1,1732 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = { + { 1,1, 1,1, 1,1, 1,1 }, + { 1,1, 0,0, 1,0, 0,0 }, + { 0,0, 1,0, 0,0, 0,1 }, + { 0,0, 0,1, 0,1, 1,0 }, +}; + +const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = { + { 0,0, 0,1, 0,1, 1,0 }, + { 0,0, 0,0, 0,0, 0,0 }, + { 1,1, 1,0, 0,1, 1,1 }, +}; + +const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = { + { -127,-127, -127,-127, -127,-127, -127,-127 }, + { -127,-127, 127, 127, -127, 127, 127, 127 }, + { 127, 127, -127, 127, 127, 127, 127,-127 }, + { 127, 127, 127,-127, 127,-127, -127, 127 }, +}; + +const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = { + { 127, 127, 127,-127, 127,-127, -127, 127 }, + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, -127, 127, 127,-127, -127,-127 }, +}; + +const ubit_t gsm0503_usf2six[8][6] = { + { 0,0,0, 0,0,0 }, + { 1,0,0, 1,0,1 }, + { 0,1,0, 1,1,0 }, + { 1,1,0, 0,1,1 }, + { 0,0,1, 0,1,1 }, + { 1,0,1, 1,1,0 }, + { 0,1,1, 1,0,1 }, + { 1,1,1, 0,0,0 }, +}; + +const ubit_t gsm0503_usf2twelve_ubit[8][12] = { + { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }, + { 1,1,0, 1,0,0, 0,0,1, 0,1,1 }, + { 0,0,1, 1,0,1, 1,1,0, 1,1,0 }, + { 1,1,1, 0,0,1, 1,1,1, 1,0,1 }, + { 0,0,0, 0,1,1, 0,1,1, 1,0,1 }, + { 1,1,0, 1,1,1, 0,1,0, 1,1,0 }, + { 0,0,1, 1,1,0, 1,0,1, 0,1,1 }, + { 1,1,1, 0,1,0, 1,0,0, 0,0,0 }, +}; + +const sbit_t gsm0503_usf2twelve_sbit[8][12] = { + { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 }, + { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 }, + { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 }, + { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 }, + { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 }, + { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 }, + { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 }, +}; + +const uint8_t gsm0503_puncture_cs2[588] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1 +}; + +const uint8_t gsm0503_puncture_cs3[676] = { + 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0 +}; + +const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = { + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p1[588] = { + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p2[588] = { + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p1[732] = { + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p2[732] = { + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p1[948] = { + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p2[948] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p3[948] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs4_p1[1116] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p2[1116] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p3[1116] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs5_p1[1404] = { + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs5_p2[1404] = { + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs6_p1[1836] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs6_p2[1836] = { + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0, + 0,1,0,0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p1[1404] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs7_p2[1404] = { + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p3[1404] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p1[1692] = { + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs8_p2[1692] = { + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p3[1692] = { + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p1[1836] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p2[1836] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p3[1836] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, +}; + +const uint16_t gsm0503_interleave_mcs5[1248] = { + 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428, + 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968, + 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575, + 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688, + 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440, + 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980, + 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942, + 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700, + 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452, + 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414, + 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954, + 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712, + 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101, + 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420, + 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960, + 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567, + 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695, + 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432, + 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972, + 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937, + 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707, + 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444, + 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409, + 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949, + 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719, + 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096, + 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427, + 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967, + 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574, + 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687, + 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439, + 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979, + 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944, + 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699, + 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451, + 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416, + 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956, + 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711, + 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103, + 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422, + 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962, + 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569, + 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694, + 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434, + 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974, + 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936, + 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706, + 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446, + 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408, + 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948, + 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718, + 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095, + 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426, + 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966, + 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573, + 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689, + 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438, + 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978, + 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943, + 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701, + 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450, + 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415, + 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955, + 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713, + 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102, + 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421, + 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961, + 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568, + 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693, + 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433, + 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973, + 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938, + 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705, + 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445, + 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410, + 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950, + 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717, + 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097, +}; + +/* this corresponds to the bit-lengths of the individual codec + * parameters as indicated in Table 1.1 of TS 06.10 */ +const uint8_t gsm0503_gsm_fr_map[76] = { + 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* this table describes the 65 most importaint bits from EFR coded + * bits as indicated in TS 05.03 (3.1.1.1) */ +const uint8_t gsm0503_gsm_efr_protected_bits[65] = { + 39, 40, 41, 42, 43, 44, 48, 87, 45, 2, + 3, 8, 10, 18, 19, 24, 46, 47,142,143, + 144,145,146,147, 92, 93,195,196, 98,137, + 148, 94,197,149,150, 95,198, 4, 5, 11, + 12, 16, 9, 6, 7, 13, 17, 20, 96,199, + 1, 14, 15, 21, 25, 26, 28,151,201,190, + 240, 88,138,191,241 +}; + +/* Encoded in-band data for speech frames */ +const ubit_t gsm0503_afs_ic_ubit[4][8] = { + { 0,0,0,0,0,0,0,0 }, + { 0,1,0,1,1,1,0,1 }, + { 1,0,1,1,1,0,1,0 }, + { 1,1,1,0,0,1,1,1 }, +}; + +const sbit_t gsm0503_afs_ic_sbit[4][8] = { + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { 127,-127, 127,-127,-127,-127, 127,-127 }, + { -127, 127,-127,-127,-127, 127,-127, 127 }, + { -127,-127,-127, 127, 127,-127,-127,-127 }, +}; + +const ubit_t gsm0503_ahs_ic_ubit[4][4] = { + { 0,0,0,0 }, + { 1,0,0,1 }, + { 1,1,1,0 }, + { 0,1,1,1 }, +}; + +const sbit_t gsm0503_ahs_ic_sbit[4][4] = { + { 127, 127, 127, 127 }, + { -127, 127, 127,-127 }, + { -127,-127,-127, 127 }, + { 127,-127,-127,-127 }, +}; + +const uint8_t gsm0503_tch_hr_interleaving[228][2] = { + { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 }, + { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 }, + { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 }, + { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 }, + { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 }, + { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 }, + { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 }, + { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 }, + { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 }, + { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 }, + { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 }, + { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 }, + { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 }, + { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 }, + { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 }, + { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 }, + { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 }, + { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 }, + { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 }, + { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 }, + { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 }, + { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 }, + { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 }, + { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 }, + { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 }, + { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 }, + { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 }, + { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 }, + { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 }, + { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 }, + { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 }, + { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 }, + { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 }, + { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 }, + { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 }, + { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 }, + { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 }, + { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 }, +}; + +/* + * 3GPP TS 05.03 5.1.9.1.2 "USF precoding" + */ +const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = { + { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, }, + { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, }, + { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, }, + { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, }, + { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, }, + { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, }, + { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, }, + { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, }, +}; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index dc8559f..1bde75d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -71,8 +71,12 @@ gsm0502_calc_paging_group; gsm0503_xcch; +gsm0503_rach; +gsm0503_sch; gsm0503_cs2; gsm0503_cs3; +gsm0503_tch_fr; +gsm0503_tch_hr; gsm0503_tch_afs_12_2; gsm0503_tch_afs_10_2; gsm0503_tch_afs_7_95; @@ -81,6 +85,124 @@ gsm0503_tch_afs_5_9; gsm0503_tch_afs_5_15; gsm0503_tch_afs_4_75; +gsm0503_tch_ahs_7_95; +gsm0503_tch_ahs_7_4; +gsm0503_tch_ahs_6_7; +gsm0503_tch_ahs_5_9; +gsm0503_tch_ahs_5_15; +gsm0503_tch_ahs_4_75; +gsm0503_pdtch_hl_hn_ubit; +gsm0503_pdtch_edge_hl_hn_ubit; +gsm0503_pdtch_hl_hn_sbit; +gsm0503_pdtch_edge_hl_hn_sbit; +gsm0503_usf2six; +gsm0503_usf2twelve_ubit; +gsm0503_usf2twelve_sbit; +gsm0503_puncture_cs2; +gsm0503_puncture_cs3; +gsm0503_puncture_mcs1_dl_hdr; +gsm0503_puncture_mcs1_ul_hdr; +gsm0503_puncture_mcs1_p1; +gsm0503_puncture_mcs1_p2; +gsm0503_puncture_mcs2_p1; +gsm0503_puncture_mcs2_p2; +gsm0503_puncture_mcs3_p1; +gsm0503_puncture_mcs3_p2; +gsm0503_puncture_mcs3_p3; +gsm0503_puncture_mcs4_p1; +gsm0503_puncture_mcs4_p2; +gsm0503_puncture_mcs4_p3; +gsm0503_puncture_mcs5_p1; +gsm0503_puncture_mcs5_p2; +gsm0503_puncture_mcs6_p1; +gsm0503_puncture_mcs6_p2; +gsm0503_puncture_mcs7_dl_hdr; +gsm0503_puncture_mcs7_ul_hdr; +gsm0503_puncture_mcs7_p1; +gsm0503_puncture_mcs7_p2; +gsm0503_puncture_mcs7_p3; +gsm0503_puncture_mcs8_p1; +gsm0503_puncture_mcs8_p2; +gsm0503_puncture_mcs8_p3; +gsm0503_puncture_mcs9_p1; +gsm0503_puncture_mcs9_p2; +gsm0503_puncture_mcs9_p3; +gsm0503_interleave_mcs5; +gsm0503_gsm_fr_map; +gsm0503_gsm_efr_protected_bits; +gsm0503_afs_ic_ubit; +gsm0503_afs_ic_sbit; +gsm0503_ahs_ic_ubit; +gsm0503_ahs_ic_sbit; +gsm0503_tch_hr_interleaving; +gsm0503_mcs5_usf_precode_table; + +gsm0503_xcch_deinterleave; +gsm0503_xcch_interleave; +gsm0503_tch_fr_deinterleave; +gsm0503_tch_fr_interleave; +gsm0503_tch_hr_deinterleave; +gsm0503_tch_hr_interleave; +gsm0503_mcs1_ul_interleave; +gsm0503_mcs1_ul_deinterleave; +gsm0503_mcs1_dl_interleave; +gsm0503_mcs1_dl_deinterleave; +gsm0503_mcs5_ul_interleave; +gsm0503_mcs5_ul_deinterleave; +gsm0503_mcs5_dl_interleave; +gsm0503_mcs5_dl_deinterleave; +gsm0503_mcs7_ul_interleave; +gsm0503_mcs7_ul_deinterleave; +gsm0503_mcs7_dl_interleave; +gsm0503_mcs7_dl_deinterleave; +gsm0503_mcs8_ul_interleave; +gsm0503_mcs8_ul_deinterleave; +gsm0503_mcs8_dl_interleave; +gsm0503_mcs8_dl_deinterleave; + +gsm0503_xcch_burst_unmap; +gsm0503_xcch_burst_map; +gsm0503_tch_burst_unmap; +gsm0503_tch_burst_map; +gsm0503_mcs5_ul_burst_map; +gsm0503_mcs5_ul_burst_unmap; +gsm0503_mcs7_ul_burst_map; +gsm0503_mcs7_ul_burst_unmap; +gsm0503_mcs5_dl_burst_map; +gsm0503_mcs5_dl_burst_unmap; +gsm0503_mcs7_dl_burst_map; +gsm0503_mcs7_dl_burst_unmap; +gsm0503_mcs5_burst_swap; + +gsm0503_fire_crc40; +gsm0503_cs234_crc16; +gsm0503_mcs_crc8_hdr; +gsm0503_mcs_crc12; +gsm0503_rach_crc6; +gsm0503_sch_crc10; +gsm0503_tch_fr_crc3; +gsm0503_tch_efr_crc8; +gsm0503_amr_crc6; + +gsm0503_egprs_mcs; +gsm0503_xcch_decode; +gsm0503_xcch_encode; +gsm0503_pdtch_decode; +gsm0503_pdtch_egprs_decode; +gsm0503_pdtch_encode; +gsm0503_pdtch_egprs_encode; +gsm0503_tch_fr_decode; +gsm0503_tch_fr_encode; +gsm0503_tch_hr_decode; +gsm0503_tch_hr_encode; +gsm0503_tch_afs_decode; +gsm0503_tch_afs_encode; +gsm0503_tch_ahs_decode; +gsm0503_tch_ahs_encode; +gsm0503_rach_decode; +gsm0503_rach_encode; +gsm0503_sch_decode; +gsm0503_sch_encode; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..7aa5a3c 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -1,7 +1,6 @@ #!/usr/bin/python2 -mod_license = """ -/* +mod_license = """/* * Copyright (C) 2011-2016 Sylvain Munaut * Copyright (C) 2016 sysmocom s.f.m.c. GmbH * @@ -27,7 +26,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, + name = "call-me", description = False, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +50,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -63,8 +68,13 @@ def _state_mask(self): return (1 << (self.k - 1)) - 1 + def combine(self, src, sel, nb): + x = src & sel + fn_xor = lambda x, y: x ^ y + return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) + def next_state(self, state, bit): - nb = combine( + nb = self.combine( (state << 1) | bit, self.poly_divider, self.k, @@ -85,9 +95,10 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -104,9 +115,9 @@ for p_n, p_d in self.polys: if self.recursive and p_d == 1: # Systematic output are replaced when in 'termination' mode - o = combine(src, self.poly_divider, self.k) + o = self.combine(src, self.poly_divider, self.k) else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -121,61 +132,118 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" if len(self.puncture): - print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p - print >>fi, "};" + # Up to 12 numbers should be placed per line + counter = 0 - print >>fi, "\n/* %s */" % self.description - print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, \ + "\nstatic const int %s_puncture[] = {" % self.name + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n};\n") + + # Write description as a multiline comment + if self.description: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Write a final definition + print >>fi, \ + "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k print >>fi, "\t.len = %d," % self.block_len print >>fi, "\t.next_output = %s_output," % self.name print >>fi, "\t.next_state = %s_state," % self.name + if self.recursive: print >>fi, "\t.next_term_output = %s_term_output," % self.name print >>fi, "\t.next_term_state = %s_term_state," % self.name + if len(self.puncture): print >>fi, "\t.puncture = %s_puncture," % self.name + print >>fi, "};" poly = lambda *args: sum([(1 << x) for x in args]) - -def combine(src, sel, nb): - x = src & sel - fn_xor = lambda x, y: x ^ y - return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) # Polynomials according to 3GPP TS 05.03 Annex B G0 = poly(0, 3, 4) @@ -188,307 +256,487 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # RACH definition + ConvolutionalCode( + 14, + CCH_poly, + name = "rach", + description = ["RACH convolutional code"] + ), -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # SCH definition + ConvolutionalCode( + 35, + CCH_poly, + name = "sch", + description = ["SCH convolutional code"] + ), -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), + + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), + + # TCH_FR definition + ConvolutionalCode( + 185, + CCH_poly, + name = "tch_fr", + description = ["TCH/F convolutional code"] + ), + + # TCH_HR definition + ConvolutionalCode( + 98, + [ + ( G4, 1 ), + ( G5, 1 ), + ( G6, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, + 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, + 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214, + 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250, + 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295, + 298, 301, 304, 307, 310, -1, + ], + name = "tch_hr", + description = ["TCH/H convolutional code"] + ), + + # TCH_AHS_7_95 definition + ConvolutionalCode( + 129, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43, + 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95, + 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151, + 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191, + 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221, + 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251, + 255, 257, 259, 261, 263, 265, -1, + ], + name = "tch_ahs_7_95", + description = ["TCH/AHS 7.95 kbits convolutional code"] + ), + + # TCH_AHS_7_4 definition + ConvolutionalCode( + 126, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55, + 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119, + 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, + 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, + 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251, + 253, 255, 257, 259, -1, + ], + name = "tch_ahs_7_4", + description = ["TCH/AHS 7.4 kbits convolutional code"] + ), + + # TCH_AHS_6_7 definition + ConvolutionalCode( + 116, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, + 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189, + 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231, + 233, 235, 237, 239, -1, + ], + name = "tch_ahs_6_7", + description = ["TCH/AHS 6.7 kbits convolutional code"] + ), + + # TCH_AHS_5_9 definition + ConvolutionalCode( + 108, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211, + 215, 219, 221, 223, -1, + ], + name = "tch_ahs_5_9", + description = ["TCH/AHS 5.9 kbits convolutional code"] + ), + + # TCH_AHS_5_15 definition + ConvolutionalCode( + 97, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33, + 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93, + 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159, + 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, + 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, + 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261, + 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289, + 291, 294, 295, 297, 298, 300, 301, -1, + ], + name = "tch_ahs_5_15", + description = ["TCH/AHS 5.15 kbits convolutional code"] + ), + + # TCH_AHS_4_75 definition + ConvolutionalCode( + 89, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34, + 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, + 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166, + 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, + 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256, + 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283, + 284, -1, + ], + name = "tch_ahs_4_75", + description = ["TCH/AHS 4.75 kbits convolutional code"] + ), +] + +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 5 16:38:24 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 5 Sep 2016 16:38:24 +0000 Subject: [PATCH] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/816 to look at the new patch set (#3). gsm0503: migrate transcoding routines from OsmoBTS The GSM 05.03 transcoding routines are becoming increasingly popular, and some projects (such as GR-GSM and OsmocomBB) also require transcoding capabilities implemented within the libosmocore. Moreover, it would be beeter to clean up the OsmoBTS source code, sharing this code. Currently there are the following data types supported: - xCCH - PDTCH - PDTCH (EDGE) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Also, the conv_gen.py was updated, and now writes a single file. The EDGE MCS convolutional codes are migrated 'as is', i.e. already in generated state. Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a --- M .gitignore M include/osmocom/gsm/gsm0503.h A include/osmocom/gsm/gsm0503_coding.h A include/osmocom/gsm/gsm0503_interleaving.h A include/osmocom/gsm/gsm0503_mapping.h A include/osmocom/gsm/gsm0503_parity.h A include/osmocom/gsm/gsm0503_tables.h M src/gsm/Makefile.am A src/gsm/gsm0503_coding.c A src/gsm/gsm0503_conv_edge.c A src/gsm/gsm0503_interleaving.c A src/gsm/gsm0503_mapping.c A src/gsm/gsm0503_parity.c A src/gsm/gsm0503_tables.c M src/gsm/libosmogsm.map M utils/conv_gen.py 16 files changed, 6,752 insertions(+), 327 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/16/816/3 diff --git a/.gitignore b/.gitignore index 5165364..dd9c61b 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ doc/*.tag src/crc*gen.c +src/gsm/gsm6*.c src/gsm/conv*gen.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index cf1c976..3fda4ce 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -26,7 +26,7 @@ #include -/*! \file conv_gen.h +/*! \file gsm0503.h * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03 */ @@ -36,10 +36,26 @@ */ extern const struct osmo_conv_code gsm0503_xcch; +/*! \brief structure describing convolutional code RACH + */ +extern const struct osmo_conv_code gsm0503_rach; + +/*! \brief structure describing convolutional code SCH + */ +extern const struct osmo_conv_code gsm0503_sch; + /*! \brief structures describing convolutional codes CS2/3 */ extern const struct osmo_conv_code gsm0503_cs2; extern const struct osmo_conv_code gsm0503_cs3; + +/*! \brief structure describing convolutional code TCH/FR + */ +extern const struct osmo_conv_code gsm0503_tch_fr; + +/*! \brief structure describing convolutional code TCH/HR + */ +extern const struct osmo_conv_code gsm0503_tch_hr; /*! \brief structure describing convolutional code TCH/AFS 12.2 */ @@ -72,3 +88,87 @@ /*! \brief structure describing convolutional code TCH/AFS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_afs_4_75; + +/*! \brief structure describing convolutional code TCH/AHS 7.95 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_95; + +/*! \brief structure describing convolutional code TCH/AHS 7.4 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_4; + +/*! \brief structure describing convolutional code TCH/AHS 6.7 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_6_7; + +/*! \brief structure describing convolutional code TCH/AHS 5.9 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_9; + +/*! \brief structure describing convolutional code TCH/AHS 5.15 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_15; + +/*! \brief structure describing convolutional code TCH/AHS 4.75 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; + +/*! \brief structure describing convolutional code EDGE MCS1 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 + */ +extern const struct osmo_conv_code gsm0503_mcs1; + +/*! \brief structure describing convolutional code EDGE MCS2 + */ +extern const struct osmo_conv_code gsm0503_mcs2; + +/*! \brief structure describing convolutional code EDGE MCS3 + */ +extern const struct osmo_conv_code gsm0503_mcs3; + +/*! \brief structure describing convolutional code EDGE MCS4 + */ +extern const struct osmo_conv_code gsm0503_mcs4; + +/*! \brief structure describing convolutional code EDGE MCS5 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 + */ +extern const struct osmo_conv_code gsm0503_mcs5; + +/*! \brief structure describing convolutional code EDGE MCS6 + */ +extern const struct osmo_conv_code gsm0503_mcs6; + +/*! \brief structure describing convolutional code EDGE MCS7 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 + */ +extern const struct osmo_conv_code gsm0503_mcs7; + +/*! \brief structure describing convolutional code EDGE MCS8 + */ +extern const struct osmo_conv_code gsm0503_mcs8; + +/*! \brief structure describing convolutional code EDGE MCS9 + */ +extern const struct osmo_conv_code gsm0503_mcs9; diff --git a/include/osmocom/gsm/gsm0503_coding.h b/include/osmocom/gsm/gsm0503_coding.h new file mode 100644 index 0000000..76f6b7a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_coding.h @@ -0,0 +1,85 @@ +/* + * GSM 05.03 transcoding routines + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +#define GSM0503_GPRS_BURSTS_NBITS (116 * 4) +#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4) + +struct osmo_conv_code; + +enum gsm0503_egprs_mcs { + EGPRS_MCS0, + EGPRS_MCS1, + EGPRS_MCS2, + EGPRS_MCS3, + EGPRS_MCS4, + EGPRS_MCS5, + EGPRS_MCS6, + EGPRS_MCS7, + EGPRS_MCS8, + EGPRS_MCS9, + EGPRS_NUM_MCS, +}; + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len); +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, uint8_t *l2_data, + uint8_t l2_len); +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, + uint16_t nbits, uint8_t *usf_p, int *n_errors, int *n_bits_total); + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int net_order); +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order, + int efr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len); +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total); + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr); +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr); +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic); +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic); + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info); +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst); diff --git a/include/osmocom/gsm/gsm0503_interleaving.h b/include/osmocom/gsm/gsm0503_interleaving.h new file mode 100644 index 0000000..3f477cc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_interleaving.h @@ -0,0 +1,72 @@ +/* + * GSM 05.03 interleaving + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); diff --git a/include/osmocom/gsm/gsm0503_mapping.h b/include/osmocom/gsm/gsm0503_mapping.h new file mode 100644 index 0000000..74a7b83 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_mapping.h @@ -0,0 +1,55 @@ +/* + * GSM 05.03 mapping + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn); +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn); + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd); +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd); + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs5_burst_swap(sbit_t *eB); diff --git a/include/osmocom/gsm/gsm0503_parity.h b/include/osmocom/gsm/gsm0503_parity.h new file mode 100644 index 0000000..fa8bacc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_parity.h @@ -0,0 +1,35 @@ +/* + * GSM 05.03 parity + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +const struct osmo_crc64gen_code gsm0503_fire_crc40; +const struct osmo_crc16gen_code gsm0503_cs234_crc16; +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr; +const struct osmo_crc16gen_code gsm0503_mcs_crc12; +const struct osmo_crc8gen_code gsm0503_rach_crc6; +const struct osmo_crc16gen_code gsm0503_sch_crc10; +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3; +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8; +const struct osmo_crc8gen_code gsm0503_amr_crc6; diff --git a/include/osmocom/gsm/gsm0503_tables.h b/include/osmocom/gsm/gsm0503_tables.h new file mode 100644 index 0000000..5ab04e5 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_tables.h @@ -0,0 +1,71 @@ +/* + * GSM 05.03 tables + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; +extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8]; +extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8]; +extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8]; +extern const ubit_t gsm0503_usf2six[8][6]; +extern const ubit_t gsm0503_usf2twelve_ubit[8][12]; +extern const sbit_t gsm0503_usf2twelve_sbit[8][12]; +extern const uint8_t gsm0503_puncture_cs2[588]; +extern const uint8_t gsm0503_puncture_cs3[676]; +extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108]; +extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117]; +extern const uint8_t gsm0503_puncture_mcs1_p1[588]; +extern const uint8_t gsm0503_puncture_mcs1_p2[588]; +extern const uint8_t gsm0503_puncture_mcs2_p1[732]; +extern const uint8_t gsm0503_puncture_mcs2_p2[732]; +extern const uint8_t gsm0503_puncture_mcs3_p1[948]; +extern const uint8_t gsm0503_puncture_mcs3_p2[948]; +extern const uint8_t gsm0503_puncture_mcs3_p3[948]; +extern const uint8_t gsm0503_puncture_mcs4_p1[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p2[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p3[1116]; +extern const uint8_t gsm0503_puncture_mcs5_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs5_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs6_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs6_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135]; +extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162]; +extern const uint8_t gsm0503_puncture_mcs7_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p3[1404]; +extern const uint8_t gsm0503_puncture_mcs8_p1[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p2[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p3[1692]; +extern const uint8_t gsm0503_puncture_mcs9_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p3[1836]; +extern const uint16_t gsm0503_interleave_mcs5[1248]; +extern const uint8_t gsm0503_gsm_fr_map[76]; +extern const uint8_t gsm0503_gsm_efr_protected_bits[65]; +extern const ubit_t gsm0503_afs_ic_ubit[4][8]; +extern const sbit_t gsm0503_afs_ic_sbit[4][8]; +extern const ubit_t gsm0503_ahs_ic_ubit[4][4]; +extern const sbit_t gsm0503_ahs_ic_sbit[4][4]; +extern const uint8_t gsm0503_tch_hr_interleaving[228][2]; +extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36]; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..13c08d6 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,16 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ + gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ + gsm0503_conv_edge.c gsm0503_tables.c \ + gsm0503_parity.c gsm0503_interleaving.c \ + gsm0503_mapping.c gsm0503_coding.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gprs_gea.c + libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +37,18 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: $(AM_V_GEN)python2 ../../utils/conv_gen.py + +# Some dependencies from libosmocodec +gsm610.c: + $(AM_V_GEN)cp ../codec/gsm610.c ./ + +gsm620.c: + $(AM_V_GEN)cp ../codec/gsm620.c ./ + +gsm660.c: + $(AM_V_GEN)cp ../codec/gsm660.c ./ + +CLEANFILES = gsm0503_conv.c gsm610.c gsm620.c gsm660.c diff --git a/src/gsm/gsm0503_coding.c b/src/gsm/gsm0503_coding.c new file mode 100644 index 0000000..49cbee7 --- /dev/null +++ b/src/gsm/gsm0503_coding.c @@ -0,0 +1,2694 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * EGPRS coding limits + */ + +/* Max header size with parity bits */ +#define EGPRS_HDR_UPP_MAX 54 + +/* Max encoded header size */ +#define EGPRS_HDR_C_MAX 162 + +/* Max punctured header size */ +#define EGPRS_HDR_HC_MAX 160 + +/* Max data block size with parity bits */ +#define EGPRS_DATA_U_MAX 612 + +/* Max encoded data block size */ +#define EGPRS_DATA_C_MAX 1836 + +/* Max single block punctured data size */ +#define EGPRS_DATA_DC_MAX 1248 + +/* Dual block punctured data size */ +#define EGPRS_DATA_C1 612 +#define EGPRS_DATA_C2 EGPRS_DATA_C1 + +/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ +#define GSM_FR_BYTES 33 +/* TS 101318 Chapter 5.2: 112 bits, no sig */ +#define GSM_HR_BYTES 14 +/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ +#define GSM_EFR_BYTES 31 + +struct gsm0503_mcs_code { + uint8_t mcs; + uint8_t usf_len; + + /* Header coding */ + uint8_t hdr_len; + uint8_t hdr_code_len; + uint8_t hdr_punc_len; + const struct osmo_conv_code *hdr_conv; + const uint8_t *hdr_punc; + + /* Data coding */ + uint16_t data_len; + uint16_t data_code_len; + uint16_t data_punc_len; + const struct osmo_conv_code *data_conv; + const uint8_t *data_punc[3]; +}; + +/* + * EGPRS UL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_ul_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + .hdr_len = 46, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +/* + * EGPRS DL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_dl_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +static int osmo_conv_decode_ber(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output, + int *n_errors, int *n_bits_total) +{ + int res, i, coded_len; + ubit_t recoded[EGPRS_DATA_C_MAX]; + + res = osmo_conv_decode(code, input, output); + + if (n_bits_total || n_errors) { + coded_len = osmo_conv_encode(code, output, recoded); + OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len); + } + + /* Count bit errors */ + if (n_errors) { + *n_errors = 0; + for (i = 0; i < coded_len; i++) { + if (! ((recoded[i] && input[i] < 0) || + (!recoded[i] && input[i] > 0)) ) + *n_errors += 1; + } + } + + if (n_bits_total) + *n_bits_total = coded_len; + + return res; +} + + +static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB, + int *n_errors, int *n_bits_total) +{ + ubit_t conv[224]; + int rv; + + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 0; +} + +static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data) +{ + ubit_t conv[224]; + + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + return 0; +} + + +/* + * GSM xCCH block transcoding + */ + +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[456]; + int i; + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL); + + gsm0503_xcch_deinterleave(cB, iB); + + return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total); +} + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data) +{ + ubit_t iB[456], cB[456], hl = 1, hn = 1; + int i; + + _xcch_encode_cB(cB, l2_data); + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn); + + return 0; +} + +/* + * EGPRS PDTCH UL block decoding + */ + +/* + * Type 3 - MCS-1,2,3,4 + * Unmapping and deinterleaving + */ +static int egprs_type3_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t iB[456], q[8]; + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + q + i * 2, q + i * 2 + 1); + } + + gsm0503_mcs1_ul_deinterleave(hc, dc, iB); + + return 0; +} + +/* + * Type 2 - MCS-5,6 + * Unmapping and deinterleaving + */ +static int egprs_type2_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_DC_MAX]; + + for (i=0; i<4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs5_ul_burst_unmap(di, burst, hi, i); + } + + gsm0503_mcs5_ul_deinterleave(hc, dc, hi, di); + + return 0; +} + +/* + * Type 1 - MCS-7,8,9 + * Unmapping and deinterleaving - Note that MCS-7 interleaver is unique + */ +static int egprs_type1_unmap(const sbit_t *bursts, sbit_t *hc, + sbit_t *c1, sbit_t *c2, int msc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_C1 * 2]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs7_ul_burst_unmap(di, burst, hi, i); + } + + if (msc == EGPRS_MCS7) + gsm0503_mcs7_ul_deinterleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_ul_deinterleave(hc, c1, c2, hi, di); + + return 0; +} + +union gprs_rlc_ul_hdr_egprs { + struct gprs_rlc_ul_header_egprs_1 type1; + struct gprs_rlc_ul_header_egprs_2 type2; + struct gprs_rlc_ul_header_egprs_3 type3; +}; + +/* + * Decode EGPRS UL header section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + */ +static int _egprs_decode_hdr(const sbit_t *hc, int mcs, + union gprs_rlc_ul_hdr_egprs *hdr) +{ + sbit_t C[EGPRS_HDR_C_MAX]; + ubit_t upp[EGPRS_HDR_UPP_MAX]; + int i, j, rc; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_ul_codes[mcs]; + + /* Skip depuncturing on MCS-5,6 header */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(C, hc, code->hdr_code_len); + goto hdr_conv_decode; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + i = code->hdr_code_len - 1; + j = code->hdr_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->hdr_punc[i]) + C[i] = hc[j--]; + else + C[i] = 0; + } + +hdr_conv_decode: + osmo_conv_decode_ber(code->hdr_conv, C, upp, NULL, NULL); + rc = osmo_crc8gen_check_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + if (rc) + return -1; + + osmo_ubit2pbit_ext((pbit_t *) hdr, 0, upp, 0, code->hdr_len, 1); + + return 0; +} + +/* + * Blind MCS header decoding based on burst length and CRC validation. + * Ignore 'q' value coding indentification. This approach provides + * the strongest chance of header recovery. + */ +static int egprs_decode_hdr(union gprs_rlc_ul_hdr_egprs *hdr, + const sbit_t *bursts, uint16_t nbits) +{ + int rc; + sbit_t hc[EGPRS_HDR_HC_MAX]; + + if (nbits == GSM0503_GPRS_BURSTS_NBITS) { + /* MCS-1,2,3,4 */ + egprs_type3_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS1, hdr); + if (!rc) + return EGPRS_HDR_TYPE3; + } else if (nbits == GSM0503_EGPRS_BURSTS_NBITS) { + /* MCS-5,6 */ + egprs_type2_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS5, hdr); + if (!rc) + return EGPRS_HDR_TYPE2; + + /* MCS-7,8,9 */ + egprs_type1_unmap(bursts, hc, NULL, NULL, EGPRS_MCS7); + rc = _egprs_decode_hdr(hc, EGPRS_MCS7, hdr); + if (!rc) + return EGPRS_HDR_TYPE1; + } + + return -1; +} + +/* + * Parse EGPRS UL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_ul_cps(struct egprs_cps *cps, + union gprs_rlc_ul_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = (hdr->type2.cps_lo << 2) | hdr->type2.cps_hi; + break; + case EGPRS_HDR_TYPE3: + bits = (hdr->type3.cps_lo << 2) | hdr->type3.cps_hi; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +#define NUM_BYTES(N) ((N + 8 - 1) / 8) + +/* + * Decode EGPRS UL data section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + * 4. Block combining (MCS-7,8,9 only) + */ +static int egprs_decode_data(uint8_t *l2_data, sbit_t *c, + int mcs, int p, int blk, + int *n_errors, int *n_bits_total) +{ + ubit_t u[EGPRS_DATA_U_MAX]; + sbit_t C[EGPRS_DATA_C_MAX]; + + int i, j, rc, data_len; + struct gsm0503_mcs_code *code; + + if (blk && mcs < EGPRS_MCS7) { + /* Invalid MCS-X block state */ + return -1; + } + + code = &gsm0503_mcs_ul_codes[mcs]; + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + /* + * MCS-1,6 - single block processing + * MCS-7,9 - dual block processing + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + i = code->data_code_len - 1; + j = code->data_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->data_punc[p][i]) + C[i] = c[j--]; + else + C[i] = 0; + } + + osmo_conv_decode_ber(code->data_conv, C, u, n_errors, n_bits_total); + rc = osmo_crc16gen_check_bits(&gsm0503_mcs_crc12, u, + data_len, u + data_len); + if (rc) + return -1; + + /* Offsets output pointer on the second block of Type 1 MCS */ + osmo_ubit2pbit_ext(l2_data, code->hdr_len + blk * data_len, + u, 0, data_len, 1); + + /* Return the number of bytes required for the bit message */ + return NUM_BYTES(code->hdr_len + code->data_len); +} + +/* + * Decode EGPRS UL message + * + * 1. Header section decoding + * 2. Extract CPS settings + * 3. Burst unmapping and deinterleaving + * 4. Data section decoding + */ +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, uint16_t nbits, + uint8_t *usf_p, int *n_errors, int *n_bits_total) +{ + sbit_t dc[EGPRS_DATA_DC_MAX]; + sbit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + int type, rc; + struct egprs_cps cps; + union gprs_rlc_ul_hdr_egprs *hdr; + + if ((nbits != GSM0503_GPRS_BURSTS_NBITS) && + (nbits != GSM0503_EGPRS_BURSTS_NBITS)) { + /* Invalid EGPRS bit length */ + return -1; + } + + hdr = (union gprs_rlc_ul_hdr_egprs *) l2_data; + type = egprs_decode_hdr(hdr, bursts, nbits); + if (egprs_parse_ul_cps(&cps, hdr, type) < 0) + return -1; + + switch (cps.mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + egprs_type3_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + egprs_type2_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + egprs_type1_unmap(bursts, NULL, c1, c2, cps.mcs); + break; + default: + /* Invalid MCS-X */ + return -1; + } + + /* Decode MCS-X block, where X = cps.mcs */ + if (cps.mcs < EGPRS_MCS7) { + rc = egprs_decode_data(l2_data, dc, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + } else { + /* MCS-7,8,9 block 1 */ + rc = egprs_decode_data(l2_data, c1, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + + /* MCS-7,8,9 block 2 */ + rc = egprs_decode_data(l2_data, c2, cps.mcs, cps.p[1], + 1, n_errors, n_bits_total); + if (rc < 0) + return -1; + } + + return rc; +} + +/* + * GSM PDTCH block transcoding + */ + +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[676], hl_hn[8]; + ubit_t conv[456]; + int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */ + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j])); + + if (i == 0 || k < best) { + best = k; + cs = i+1; + } + } + + gsm0503_xcch_deinterleave(cB, iB); + + switch (cs) { + case 1: + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 23; + case 2: + for (i = 587, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs2[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs2, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 271, conv + 3 + 271); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1); + + return 34; + case 3: + for (i = 675, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs3[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs3, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 315, conv + 3 + 315); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1); + + return 40; + case 4: + for (i = 12; i < 456; i++) + conv[i] = (cB[i] < 0) ? 1 : 0; + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 12; j++) + k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[9] = usf & 1; + conv[10] = (usf >> 1) & 1; + conv[11] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 9, 431, conv + 9 + 431); + if (rv) { + *n_bits_total = 456 - 12; + *n_errors = *n_bits_total; + return -1; + } + + *n_bits_total = 456 - 12; + *n_errors = 0; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1); + + return 54; + default: + *n_bits_total = 0; + *n_errors = 0; + break; + } + + return -1; +} + +/* + * EGPRS PDTCH UL block encoding + */ +static int egprs_type3_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + ubit_t iB[456]; + const ubit_t *hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + gsm0503_mcs1_dl_interleave(gsm0503_usf2six[usf], hc, dc, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return 0; +} + +static int egprs_type2_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_DC_MAX]; + + gsm0503_mcs5_dl_interleave(hc, dc, hi, di); + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs5_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_type1_map(ubit_t *bursts, ubit_t *hc, + ubit_t *c1, ubit_t *c2, int usf, int mcs) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_C1 * 2]; + + if (mcs == EGPRS_MCS7) + gsm0503_mcs7_dl_interleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_dl_interleave(hc, c1, c2, hi, di); + + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs7_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_encode_hdr(ubit_t *hc, uint8_t *l2_data, int mcs) +{ + int i, j; + ubit_t upp[EGPRS_HDR_UPP_MAX], C[EGPRS_HDR_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + osmo_pbit2ubit_ext(upp, 0, l2_data, code->usf_len, code->hdr_len, 1); + osmo_crc8gen_set_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + + osmo_conv_encode(code->hdr_conv, upp, C); + + /* MCS-5,6 header direct puncture instead of table */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(hc, C, code->hdr_code_len); + hc[99] = hc[98]; + return 0; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->hdr_code_len; i++) { + if (!code->hdr_punc[i]) + hc[j++] = C[i]; + } + + return 0; +} + +static int egprs_encode_data(ubit_t *c, uint8_t *l2_data, + int mcs, int p, int blk) +{ + int i, j, data_len; + ubit_t u[EGPRS_DATA_U_MAX], C[EGPRS_DATA_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + /* + * Dual block - MCS-7,8,9 + * Single block - MCS-1,2,3,4,5,6 + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + osmo_pbit2ubit_ext(u, 0, l2_data, + code->usf_len + code->hdr_len + blk * data_len, data_len, 1); + + osmo_crc16gen_set_bits(&gsm0503_mcs_crc12, u, data_len, u + data_len); + + osmo_conv_encode(code->data_conv, u, C); + + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->data_code_len; i++) { + if (!code->data_punc[p][i]) + c[j++] = C[i]; + } + + return 0; +} + +union gprs_rlc_dl_hdr_egprs { + struct gprs_rlc_dl_header_egprs_1 type1; + struct gprs_rlc_dl_header_egprs_2 type2; + struct gprs_rlc_dl_header_egprs_3 type3; +}; + +/* + * Parse EGPRS DL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_dl_cps(struct egprs_cps *cps, + union gprs_rlc_dl_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = hdr->type2.cps; + break; + case EGPRS_HDR_TYPE3: + bits = hdr->type3.cps; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * EGPRS DL message encoding + */ +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, + uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t hc[EGPRS_DATA_C_MAX], dc[EGPRS_DATA_DC_MAX]; + ubit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + uint8_t mcs; + struct egprs_cps cps; + union gprs_rlc_dl_hdr_egprs *hdr; + + switch (l2_len) { + case 27: + mcs = EGPRS_MCS1; + break; + case 33: + mcs = EGPRS_MCS2; + break; + case 42: + mcs = EGPRS_MCS3; + break; + case 49: + mcs = EGPRS_MCS4; + break; + case 60: + mcs = EGPRS_MCS5; + break; + case 78: + mcs = EGPRS_MCS6; + break; + case 118: + mcs = EGPRS_MCS7; + break; + case 142: + mcs = EGPRS_MCS8; + break; + case 154: + mcs = EGPRS_MCS9; + break; + default: + return -1; + } + + /* Read header for USF and puncturing matrix selection. */ + hdr = (union gprs_rlc_dl_hdr_egprs *) l2_data; + + switch (mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + /* Check for valid CPS and matching MCS to message size */ + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE3) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type3_map(bursts, hc, dc, hdr->type3.usf); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE2) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type2_map(bursts, hc, dc, hdr->type2.usf); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE1) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(c1, l2_data, mcs, cps.p[0], 0); + egprs_encode_data(c2, l2_data, mcs, cps.p[1], 1); + egprs_type1_map(bursts, hc, c1, c2, hdr->type1.usf, mcs); + break; + } + + return mcs >= EGPRS_MCS5 ? GSM0503_EGPRS_BURSTS_NBITS : + GSM0503_GPRS_BURSTS_NBITS; + +bad_header: + /* Invalid EGPRS MCS-X header */ + return -1; +} + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t iB[456], cB[676]; + const ubit_t *hl_hn; + ubit_t conv[334]; + int i, j, usf; + + switch (l2_len) { + case 23: + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[0]; + + break; + case 34: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 271, conv + 3 + 271); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs2, conv, cB); + + for (i = 0, j = 0; i < 588; i++) + if (!gsm0503_puncture_cs2[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[1]; + + break; + case 40: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 315, conv + 3 + 315); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs3, conv, cB); + + for (i = 0, j = 0; i < 676; i++) + if (!gsm0503_puncture_cs3[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[2]; + + break; + case 54: + osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9, + 431, cB + 9 + 431); + + memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + break; + default: + return -1; + } + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return GSM0503_GPRS_BURSTS_NBITS; +} + + +/* + * GSM TCH/F FR/EFR transcoding + */ + +static void tch_fr_reassemble(uint8_t *tch_data, + ubit_t *b_bits, int net_order) +{ + int i, j, k, l, o; + + tch_data[0] = 0xd << 4; + memset(tch_data + 1, 0, 32); + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); + + return; + } + + /* reassemble d-bits */ + i = 0; /* counts bits */ + j = 4; /* counts output bits */ + k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset input bits */ + while (i < 260) { + tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7))); + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l]-1; + } + i++; + j++; + } +} + +static void tch_fr_disassemble(ubit_t *b_bits, + uint8_t *tch_data, int net_order) +{ + int i, j, k, l, o; + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + + return; + } + + i = 0; /* counts bits */ + j = 4; /* counts input bits */ + k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset output bits */ + while (i < 260) { + b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l] - 1; + } + i++; + j++; + } +} + +static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0x00; /* F = 0, FT = 000 */ + memset(tch_data + 1, 0, 14); + + for (i = 0, j = 8; i < 112; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 8; i < 112; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0xc << 4; + memset(tch_data + 1, 0, 30); + + for (i = 0, j = 4; i < 244; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 4; i < 244; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len) +{ + int i, j; + + memset(tch_data, 0, (len + 7) >> 3); + + for (i = 0, j = 0; i < len; i++, j++) + tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7))); +} + +static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len) +{ + int i, j; + + for (i = 0, j = 0; i < len; i++, j++) + d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm610_bitorder[i]] = d_bits[i]; +} + +static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm610_bitorder[i]]; +} + +static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + const uint16_t *map; + + if (!b_bits[34] && !b_bits[35]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + d_bits[i] = b_bits[map[i]]; +} + +static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm660_bitorder[i]] = d_bits[i]; +} + +static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm660_bitorder[i]]; +} + +static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 65; i++) + b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1]; +} + +static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + int i; + + for (i = 0; i < 91; i++) { + d[i << 1] = u[i]; + d[(i << 1) + 1] = u[184 - i]; + } + + for (i = 0; i < 3; i++) + p[i] = u[91 + i]; +} + +static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + int i; + + for (i = 0; i < 91; i++) { + u[i] = d[i << 1]; + u[184 - i] = d[(i << 1) + 1]; + } + + for (i = 0; i < 3; i++) + u[91 + i] = p[i]; +} + +static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + memcpy(d, u, 95); + memcpy(p, u + 95, 3); +} + +static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + memcpy(u, d, 95); + memcpy(u + 95, p, 3); +} + +static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p) +{ + memcpy(w, s, 71); + w[71] = w[72] = s[69]; + memcpy(w + 73, s + 71, 50); + w[123] = w[124] = s[119]; + memcpy(w + 125, s + 121, 53); + w[178] = w[179] = s[172]; + memcpy(w + 180, s + 174, 50); + w[230] = w[231] = s[222]; + memcpy(w + 232, s + 224, 20); + memcpy(w + 252, p, 8); +} + +static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w) +{ + int sum; + + memcpy(s, w, 71); + sum = s[69] + w[71] + w[72]; + s[69] = (sum > 2); + memcpy(s + 71, w + 73, 50); + sum = s[119] + w[123] + w[124]; + s[119] = (sum > 2); + memcpy(s + 121, w + 125, 53); + sum = s[172] + w[178] + w[179]; + s[172] = (sum > 2); + memcpy(s + 174, w + 180, 50); + sum = s[220] + w[230] + w[231]; + s[222] = (sum > 2); + memcpy(s + 224, w + 232, 20); + memcpy(p, w + 252, 8); +} + +static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot) +{ + memcpy(u, d, prot); + memcpy(u + prot, p, 6); + memcpy(u + prot + 6, d + prot, len - prot); +} + +static void tch_amr_unmerge(ubit_t *d, ubit_t *p, + ubit_t *u, int len, int prot) +{ + memcpy(d, u, prot); + memcpy(p, u+prot, 6); + memcpy(d + prot, u + prot + 6, len - prot); +} + +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, + int net_order, int efr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[185], s[244], w[260], b[65], d[260], p[8]; + int i, rv, len, steal = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return 23; + } + + osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total); + + tch_fr_unreorder(d, p, conv); + + for (i = 0; i < 78; i++) + d[i + 182] = (cB[i + 378] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p); + if (rv) { + /* Error checking CRC8 for the FR part of an EFR/FR frame */ + return -1; + } + + if (efr) { + tch_efr_d_to_w(w, d); + + tch_efr_unreorder(s, p, w); + + tch_efr_protected(s, b); + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p); + if (rv) { + /* Error checking CRC8 for the EFR part of an EFR frame */ + return -1; + } + + tch_efr_reassemble(tch_data, s); + + len = GSM_EFR_BYTES; + } else { + tch_fr_d_to_b(w, d); + + tch_fr_reassemble(tch_data, w, net_order); + + len = GSM_FR_BYTES; + } + + return len; +} + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, + int len, int net_order) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[185], w[260], b[65], s[244], d[260], p[8]; + int i; + + switch (len) { + case GSM_EFR_BYTES: /* TCH EFR */ + + tch_efr_disassemble(s, tch_data); + + tch_efr_protected(s, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p); + + tch_efr_reorder(w, s, p); + + tch_efr_w_to_d(d, w); + + goto coding_efr_fr; + case GSM_FR_BYTES: /* TCH FR */ + tch_fr_disassemble(w, tch_data, net_order); + + tch_fr_b_to_d(d, w); + +coding_efr_fr: + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p); + + tch_fr_reorder(conv, d, p); + + memcpy(cB + 378, d + 182, 78); + + osmo_conv_encode(&gsm0503_tch_fr, conv, cB); + + h = 0; + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + break; + default: + return -1; + } + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; +} + +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i, rv, steal = 0; + + /* Only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* If we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total); + + tch_hr_unreorder(d, p, conv); + + for (i = 0; i < 17; i++) + d[i + 95] = (cB[i + 211] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + if (rv) { + /* Error checking CRC8 for an HR frame */ + return -1; + } + + tch_hr_d_to_b(b, d); + + tch_hr_reassemble(tch_data, b); + + return 15; +} + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i; + + switch (len) { + case 15: /* TCH HR */ + tch_hr_disassemble(b, tch_data); + + tch_hr_b_to_d(d, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + + tch_hr_reorder(conv, d, p); + + osmo_conv_encode(&gsm0503_tch_hr, conv, cB); + + memcpy(cB + 211, d + 95, 17); + + h = 0; + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 1); + } + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i=0; i<6; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + for (i=2; i<4; i++) { + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + } + + break; + default: + return -1; + } + + return 0; +} + +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + *n_errors = 0; *n_bits_total = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 7: /* TCH/AFS12.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 244, 81); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p); + if (rv) { + /* Error checking CRC8 for an AMR 12.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 244); + + len = 31; + + break; + case 6: /* TCH/AFS10.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 204, 65); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p); + if (rv) { + /* Error checking CRC8 for an AMR 10.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 204); + + len = 26; + + break; + case 5: /* TCH/AFS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 159, 75); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AFS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 148, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AFS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 134, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AFS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 118, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AFS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 103, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AFS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 95, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 448; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + goto facch; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID is not in codec list! */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID is not in codec list! */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 7: /* TCH/AFS12.2 */ + if (len != 31) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 244); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p); + + tch_amr_merge(conv, d, p, 244, 81); + + osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8); + + break; + case 6: /* TCH/AFS10.2 */ + if (len != 26) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 204); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p); + + tch_amr_merge(conv, d, p, 204, 65); + + osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8); + + break; + case 5: /* TCH/AFS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p); + + tch_amr_merge(conv, d, p, 159, 75); + + osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8); + + break; + case 4: /* TCH/AFS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 148, 61); + + osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8); + + break; + case 3: /* TCH/AFS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 134, 55); + + osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8); + + break; + case 2: /* TCH/AFS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 118, 55); + + osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8); + + break; + case 1: /* TCH/AFS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 103, 49); + + osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8); + + break; + case 0: /* TCH/AFS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 95, 39); + + osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 8); + +facch: + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + + /* only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* if we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 4; j++) + k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 5: /* TCH/AHS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 123, 67); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + for (i = 0; i < 36; i++) + d[i + 123] = (cB[i + 192] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AHS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 120, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + for (i = 0; i < 28; i++) + d[i + 120] = (cB[i + 200] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AHS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 110, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + for (i = 0; i < 24; i++) + d[i + 110] = (cB[i + 204] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AHS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 102, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + for (i = 0; i < 16; i++) + d[i + 102] = (cB[i + 212] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AHS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 91, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 91] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AHS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 83, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 83] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 159; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 6; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], + &h, i >> 2); + for (i = 2; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + + return 0; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID %d not in codec list */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID %d not in codec list */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 5: /* TCH/AHS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p); + + tch_amr_merge(conv, d, p, 123, 67); + + osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4); + + memcpy(cB + 192, d + 123, 36); + + break; + case 4: /* TCH/AHS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 120, 61); + + osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4); + + memcpy(cB + 200, d + 120, 28); + + break; + case 3: /* TCH/AHS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 110, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4); + + memcpy(cB + 204, d + 110, 24); + + break; + case 2: /* TCH/AHS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 102, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4); + + memcpy(cB + 212, d + 102, 16); + + break; + case 1: /* TCH/AHS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 91, 49); + + osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4); + + memcpy(cB + 216, d + 91, 12); + + break; + case 0: /* TCH/AHS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 83, 39); + + osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4); + + memcpy(cB + 216, d + 83, 12); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 4); + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1); + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +/* + * GSM RACH transcoding + */ + +/* + * GSM RACH apply BSIC to parity + * + * p(j) = p(j) xor b(j) j = 0, ..., 5 + * b(0) = MSB of PLMN colour code + * b(5) = LSB of BS colour code + */ + +static int rach_apply_bsic(ubit_t *d, uint8_t bsic) +{ + int i; + + /* Apply it */ + for (i = 0; i < 6; i++) + d[8 + i] ^= ((bsic >> (5 - i)) & 1); + + return 0; +} + +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic) +{ + ubit_t conv[14]; + int rv; + + osmo_conv_decode(&gsm0503_rach, burst, conv); + + rach_apply_bsic(conv, bsic); + + rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + if (rv) + return -1; + + osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1); + + return 0; +} + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic) +{ + ubit_t conv[14]; + + osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1); + + osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + + rach_apply_bsic(conv, bsic); + + osmo_conv_encode(&gsm0503_rach, conv, burst); + + return 0; +} + + +/* + * GSM SCH transcoding + */ + +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst) +{ + ubit_t conv[35]; + int rv; + + osmo_conv_decode(&gsm0503_sch, burst, conv); + + rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + if (rv) + return -1; + + osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1); + + return 0; +} + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info) +{ + ubit_t conv[35]; + + osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1); + + osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + + osmo_conv_encode(&gsm0503_sch, conv, burst); + + return 0; +} diff --git a/src/gsm/gsm0503_conv_edge.c b/src/gsm/gsm0503_conv_edge.c new file mode 100644 index 0000000..a542323 --- /dev/null +++ b/src/gsm/gsm0503_conv_edge.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2016 Tom Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +static const uint8_t conv_mcs_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, +}; + +static const uint8_t conv_mcs_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + + +const struct osmo_conv_code gsm0503_mcs1_dl_hdr = { + .N = 3, + .K = 7, + .len = 36, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1_ul_hdr = { + .N = 3, + .K = 7, + .len = 39, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1 = { + .N = 3, + .K = 7, + .len = 190, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs2 = { + .N = 3, + .K = 7, + .len = 238, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs3 = { + .N = 3, + .K = 7, + .len = 310, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs4 = { + .N = 3, + .K = 7, + .len = 366, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_dl_hdr = { + .N = 3, + .K = 7, + .len = 33, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_ul_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs6 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_dl_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_ul_hdr = { + .N = 3, + .K = 7, + .len = 54, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs8 = { + .N = 3, + .K = 7, + .len = 558, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs9 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; diff --git a/src/gsm/gsm0503_interleaving.c b/src/gsm/gsm0503_interleaving.c new file mode 100644 index 0000000..0c1b8a0 --- /dev/null +++ b/src/gsm/gsm0503_interleaving.c @@ -0,0 +1,574 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include +#include + +/* + * GSM xCCH interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 4 blocks of 114 bits: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 4) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (u) { + for (k=0; k<12; k++) + u[k] = c[k]; + } + + if (hc) { + for (k=12; k<80; k++) + hc[k - 12] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<12; k++) + c[k] = up[k]; + for (k=12; k<80; k++) + c[k] = hc[k - 12]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (hc) { + for (k=0; k<80; k++) + hc[k] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<80; k++) + c[k] = hc[k]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +/* + * GSM TCH FR/EFR/AFS interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 8 blocks of 114 bits, + * where even bits of the first 4 blocks and odd bits of the last 4 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 8) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +/* + * GSM TCH HR/AHS interleaving and burst mapping + * + * Interleaving: + * + * Given 288 coded input bits, form 4 blocks of 114 bits, + * where even bits of the first 2 blocks and odd bits of the last 2 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 227 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 2n + b + * j, b = table[k]; + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + iB[B * 114 + j] = cB[k]; + } +} + diff --git a/src/gsm/gsm0503_mapping.c b/src/gsm/gsm0503_mapping.c new file mode 100644 index 0000000..c2079b9 --- /dev/null +++ b/src/gsm/gsm0503_mapping.c @@ -0,0 +1,291 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn) +{ + memcpy(iB, eB, 57); + memcpy(iB+57, eB+59, 57); + + if (hl) + *hl = eB[57]; + + if (hn) + *hn = eB[58]; +} + +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn) +{ + memcpy(eB, iB, 57); + memcpy(eB+59, iB+57, 57); + + if (hl) + eB[57] = *hl; + if (hn) + eB[58] = *hn; +} + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (iB) { + for (i=odd; i<57; i+=2) + iB[i] = eB[i]; + for (i=58-odd; i<114; i+=2) + iB[i] = eB[i+2]; + } + + if (h) { + if (!odd) + *h = eB[58]; + else + *h = eB[57]; + } +} + +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (eB) { + for (i=odd; i<57; i+=2) + eB[i] = iB[i]; + for (i=58-odd; i<114; i+=2) + eB[i+2] = iB[i]; + } + + if (h) { + if (!odd) + eB[58] = *h; + else + eB[57] = *h; + } +} + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<168; j++) + eB[j] = hi[25*B+j-156]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<192; j++) + eB[j] = hi[25*B+j-167]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<168; j++) + hi[25*B+j-156] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<192; j++) + hi[25*B+j-167] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<174; j++) + eB[j] = hi[34*B+j-156]; + for (j=174; j<176; j++) + eB[j] = 0; + for (j=176; j<192; j++) + eB[j] = hi[34*B+j-158]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<174; j++) + hi[34*B+j-156] = eB[j]; + for (j=176; j<192; j++) + hi[34*B+j-158] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<168; j++) + eB[j] = hi[31*B+j-153]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<195; j++) + eB[j] = hi[31*B+j-164]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<168; j++) + hi[31*B+j-153] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<195; j++) + hi[31*B+j-164] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<174; j++) + eB[j] = hi[40*B+j-153]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<195; j++) + eB[j] = hi[40*B+j-155]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<174; j++) + hi[40*B+j-153] = eB[j]; + + for (j=176; j<195; j++) + hi[40*B+j-155] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs5_burst_swap(sbit_t *eB) +{ + sbit_t t[14]; + + t[0] = eB[155]; + t[1] = eB[158]; + t[2] = eB[161]; + t[3] = eB[164]; + t[4] = eB[167]; + t[5] = eB[170]; + t[6] = eB[173]; + t[7] = eB[195]; + t[8] = eB[196]; + t[9] = eB[198]; + t[10] = eB[199]; + t[11] = eB[201]; + t[12] = eB[202]; + t[13] = eB[204]; + + eB[155] = eB[142]; + eB[158] = eB[144]; + eB[161] = eB[145]; + eB[164] = eB[147]; + eB[167] = eB[148]; + eB[170] = eB[150]; + eB[173] = eB[151]; + eB[195] = eB[176]; + eB[196] = eB[179]; + eB[198] = eB[182]; + eB[199] = eB[185]; + eB[201] = eB[188]; + eB[202] = eB[191]; + eB[204] = eB[194]; + + eB[142] = t[0]; + eB[144] = t[1]; + eB[145] = t[2]; + eB[147] = t[3]; + eB[148] = t[4]; + eB[150] = t[5]; + eB[151] = t[6]; + eB[176] = t[7]; + eB[179] = t[8]; + eB[182] = t[9]; + eB[185] = t[10]; + eB[188] = t[11]; + eB[191] = t[12]; + eB[194] = t[13]; +} diff --git a/src/gsm/gsm0503_parity.c b/src/gsm/gsm0503_parity.c new file mode 100644 index 0000000..c9cfba4 --- /dev/null +++ b/src/gsm/gsm0503_parity.c @@ -0,0 +1,145 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +/* + * GSM (SACCH) parity (FIRE code) + * + * g(x) = (x^23 + 1)(x^17 + x^3 + 1) + * = x^40 + x^26 + x^23 + x^17 + x^3 + a1 + */ + +const struct osmo_crc64gen_code gsm0503_fire_crc40 = { + .bits = 40, + .poly = 0x0004820009ULL, + .init = 0x0000000000ULL, + .remainder = 0xffffffffffULL, +}; + + +/* + * GSM PDTCH CS-2, CS-3, CS-4 parity + * + * g(x) = x^16 + x^12 + x^5 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_cs234_crc16 = { + .bits = 16, + .poly = 0x1021, + .init = 0x0000, + .remainder = 0xffff, +}; + +/* + * EDGE MCS header parity + * + */ + +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = { + .bits = 8, + .poly = 0x49, + .init = 0x00, + .remainder = 0xff, +}; + +/* + * EDGE MCS data parity + * + */ + +const struct osmo_crc16gen_code gsm0503_mcs_crc12 = { + .bits = 12, + .poly = 0x0d31, + .init = 0x0000, + .remainder = 0x0fff, +}; + +/* + * GSM RACH parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_rach_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + + +/* + * GSM SCH parity + * + * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_sch_crc10 = { + .bits = 10, + .poly = 0x175, + .init = 0x000, + .remainder = 0x3ff, +}; + + +/* + * GSM TCH FR/HR/EFR parity + * + * g(x) = x^3 + x + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = { + .bits = 3, + .poly = 0x3, + .init = 0x0, + .remainder = 0x7, +}; + +/* + * GSM TCH EFR parity + * + * g(x) = x^8 + x^4 + x^3 + x^2 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = { + .bits = 8, + .poly = 0x1d, + .init = 0x00, + .remainder = 0x00, +}; + +/* + * GSM AMR parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_amr_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + diff --git a/src/gsm/gsm0503_tables.c b/src/gsm/gsm0503_tables.c new file mode 100644 index 0000000..95132b1 --- /dev/null +++ b/src/gsm/gsm0503_tables.c @@ -0,0 +1,1732 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = { + { 1,1, 1,1, 1,1, 1,1 }, + { 1,1, 0,0, 1,0, 0,0 }, + { 0,0, 1,0, 0,0, 0,1 }, + { 0,0, 0,1, 0,1, 1,0 }, +}; + +const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = { + { 0,0, 0,1, 0,1, 1,0 }, + { 0,0, 0,0, 0,0, 0,0 }, + { 1,1, 1,0, 0,1, 1,1 }, +}; + +const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = { + { -127,-127, -127,-127, -127,-127, -127,-127 }, + { -127,-127, 127, 127, -127, 127, 127, 127 }, + { 127, 127, -127, 127, 127, 127, 127,-127 }, + { 127, 127, 127,-127, 127,-127, -127, 127 }, +}; + +const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = { + { 127, 127, 127,-127, 127,-127, -127, 127 }, + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, -127, 127, 127,-127, -127,-127 }, +}; + +const ubit_t gsm0503_usf2six[8][6] = { + { 0,0,0, 0,0,0 }, + { 1,0,0, 1,0,1 }, + { 0,1,0, 1,1,0 }, + { 1,1,0, 0,1,1 }, + { 0,0,1, 0,1,1 }, + { 1,0,1, 1,1,0 }, + { 0,1,1, 1,0,1 }, + { 1,1,1, 0,0,0 }, +}; + +const ubit_t gsm0503_usf2twelve_ubit[8][12] = { + { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }, + { 1,1,0, 1,0,0, 0,0,1, 0,1,1 }, + { 0,0,1, 1,0,1, 1,1,0, 1,1,0 }, + { 1,1,1, 0,0,1, 1,1,1, 1,0,1 }, + { 0,0,0, 0,1,1, 0,1,1, 1,0,1 }, + { 1,1,0, 1,1,1, 0,1,0, 1,1,0 }, + { 0,0,1, 1,1,0, 1,0,1, 0,1,1 }, + { 1,1,1, 0,1,0, 1,0,0, 0,0,0 }, +}; + +const sbit_t gsm0503_usf2twelve_sbit[8][12] = { + { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 }, + { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 }, + { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 }, + { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 }, + { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 }, + { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 }, + { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 }, +}; + +const uint8_t gsm0503_puncture_cs2[588] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1 +}; + +const uint8_t gsm0503_puncture_cs3[676] = { + 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0 +}; + +const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = { + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p1[588] = { + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p2[588] = { + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p1[732] = { + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p2[732] = { + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p1[948] = { + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p2[948] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p3[948] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs4_p1[1116] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p2[1116] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p3[1116] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs5_p1[1404] = { + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs5_p2[1404] = { + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs6_p1[1836] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs6_p2[1836] = { + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0, + 0,1,0,0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p1[1404] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs7_p2[1404] = { + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p3[1404] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p1[1692] = { + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs8_p2[1692] = { + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p3[1692] = { + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p1[1836] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p2[1836] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p3[1836] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, +}; + +const uint16_t gsm0503_interleave_mcs5[1248] = { + 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428, + 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968, + 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575, + 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688, + 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440, + 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980, + 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942, + 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700, + 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452, + 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414, + 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954, + 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712, + 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101, + 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420, + 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960, + 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567, + 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695, + 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432, + 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972, + 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937, + 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707, + 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444, + 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409, + 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949, + 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719, + 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096, + 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427, + 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967, + 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574, + 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687, + 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439, + 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979, + 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944, + 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699, + 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451, + 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416, + 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956, + 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711, + 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103, + 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422, + 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962, + 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569, + 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694, + 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434, + 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974, + 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936, + 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706, + 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446, + 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408, + 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948, + 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718, + 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095, + 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426, + 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966, + 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573, + 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689, + 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438, + 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978, + 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943, + 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701, + 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450, + 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415, + 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955, + 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713, + 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102, + 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421, + 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961, + 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568, + 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693, + 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433, + 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973, + 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938, + 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705, + 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445, + 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410, + 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950, + 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717, + 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097, +}; + +/* this corresponds to the bit-lengths of the individual codec + * parameters as indicated in Table 1.1 of TS 06.10 */ +const uint8_t gsm0503_gsm_fr_map[76] = { + 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* this table describes the 65 most importaint bits from EFR coded + * bits as indicated in TS 05.03 (3.1.1.1) */ +const uint8_t gsm0503_gsm_efr_protected_bits[65] = { + 39, 40, 41, 42, 43, 44, 48, 87, 45, 2, + 3, 8, 10, 18, 19, 24, 46, 47,142,143, + 144,145,146,147, 92, 93,195,196, 98,137, + 148, 94,197,149,150, 95,198, 4, 5, 11, + 12, 16, 9, 6, 7, 13, 17, 20, 96,199, + 1, 14, 15, 21, 25, 26, 28,151,201,190, + 240, 88,138,191,241 +}; + +/* Encoded in-band data for speech frames */ +const ubit_t gsm0503_afs_ic_ubit[4][8] = { + { 0,0,0,0,0,0,0,0 }, + { 0,1,0,1,1,1,0,1 }, + { 1,0,1,1,1,0,1,0 }, + { 1,1,1,0,0,1,1,1 }, +}; + +const sbit_t gsm0503_afs_ic_sbit[4][8] = { + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { 127,-127, 127,-127,-127,-127, 127,-127 }, + { -127, 127,-127,-127,-127, 127,-127, 127 }, + { -127,-127,-127, 127, 127,-127,-127,-127 }, +}; + +const ubit_t gsm0503_ahs_ic_ubit[4][4] = { + { 0,0,0,0 }, + { 1,0,0,1 }, + { 1,1,1,0 }, + { 0,1,1,1 }, +}; + +const sbit_t gsm0503_ahs_ic_sbit[4][4] = { + { 127, 127, 127, 127 }, + { -127, 127, 127,-127 }, + { -127,-127,-127, 127 }, + { 127,-127,-127,-127 }, +}; + +const uint8_t gsm0503_tch_hr_interleaving[228][2] = { + { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 }, + { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 }, + { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 }, + { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 }, + { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 }, + { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 }, + { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 }, + { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 }, + { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 }, + { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 }, + { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 }, + { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 }, + { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 }, + { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 }, + { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 }, + { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 }, + { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 }, + { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 }, + { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 }, + { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 }, + { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 }, + { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 }, + { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 }, + { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 }, + { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 }, + { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 }, + { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 }, + { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 }, + { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 }, + { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 }, + { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 }, + { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 }, + { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 }, + { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 }, + { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 }, + { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 }, + { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 }, + { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 }, +}; + +/* + * 3GPP TS 05.03 5.1.9.1.2 "USF precoding" + */ +const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = { + { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, }, + { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, }, + { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, }, + { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, }, + { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, }, + { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, }, + { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, }, + { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, }, +}; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index dc8559f..1bde75d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -71,8 +71,12 @@ gsm0502_calc_paging_group; gsm0503_xcch; +gsm0503_rach; +gsm0503_sch; gsm0503_cs2; gsm0503_cs3; +gsm0503_tch_fr; +gsm0503_tch_hr; gsm0503_tch_afs_12_2; gsm0503_tch_afs_10_2; gsm0503_tch_afs_7_95; @@ -81,6 +85,124 @@ gsm0503_tch_afs_5_9; gsm0503_tch_afs_5_15; gsm0503_tch_afs_4_75; +gsm0503_tch_ahs_7_95; +gsm0503_tch_ahs_7_4; +gsm0503_tch_ahs_6_7; +gsm0503_tch_ahs_5_9; +gsm0503_tch_ahs_5_15; +gsm0503_tch_ahs_4_75; +gsm0503_pdtch_hl_hn_ubit; +gsm0503_pdtch_edge_hl_hn_ubit; +gsm0503_pdtch_hl_hn_sbit; +gsm0503_pdtch_edge_hl_hn_sbit; +gsm0503_usf2six; +gsm0503_usf2twelve_ubit; +gsm0503_usf2twelve_sbit; +gsm0503_puncture_cs2; +gsm0503_puncture_cs3; +gsm0503_puncture_mcs1_dl_hdr; +gsm0503_puncture_mcs1_ul_hdr; +gsm0503_puncture_mcs1_p1; +gsm0503_puncture_mcs1_p2; +gsm0503_puncture_mcs2_p1; +gsm0503_puncture_mcs2_p2; +gsm0503_puncture_mcs3_p1; +gsm0503_puncture_mcs3_p2; +gsm0503_puncture_mcs3_p3; +gsm0503_puncture_mcs4_p1; +gsm0503_puncture_mcs4_p2; +gsm0503_puncture_mcs4_p3; +gsm0503_puncture_mcs5_p1; +gsm0503_puncture_mcs5_p2; +gsm0503_puncture_mcs6_p1; +gsm0503_puncture_mcs6_p2; +gsm0503_puncture_mcs7_dl_hdr; +gsm0503_puncture_mcs7_ul_hdr; +gsm0503_puncture_mcs7_p1; +gsm0503_puncture_mcs7_p2; +gsm0503_puncture_mcs7_p3; +gsm0503_puncture_mcs8_p1; +gsm0503_puncture_mcs8_p2; +gsm0503_puncture_mcs8_p3; +gsm0503_puncture_mcs9_p1; +gsm0503_puncture_mcs9_p2; +gsm0503_puncture_mcs9_p3; +gsm0503_interleave_mcs5; +gsm0503_gsm_fr_map; +gsm0503_gsm_efr_protected_bits; +gsm0503_afs_ic_ubit; +gsm0503_afs_ic_sbit; +gsm0503_ahs_ic_ubit; +gsm0503_ahs_ic_sbit; +gsm0503_tch_hr_interleaving; +gsm0503_mcs5_usf_precode_table; + +gsm0503_xcch_deinterleave; +gsm0503_xcch_interleave; +gsm0503_tch_fr_deinterleave; +gsm0503_tch_fr_interleave; +gsm0503_tch_hr_deinterleave; +gsm0503_tch_hr_interleave; +gsm0503_mcs1_ul_interleave; +gsm0503_mcs1_ul_deinterleave; +gsm0503_mcs1_dl_interleave; +gsm0503_mcs1_dl_deinterleave; +gsm0503_mcs5_ul_interleave; +gsm0503_mcs5_ul_deinterleave; +gsm0503_mcs5_dl_interleave; +gsm0503_mcs5_dl_deinterleave; +gsm0503_mcs7_ul_interleave; +gsm0503_mcs7_ul_deinterleave; +gsm0503_mcs7_dl_interleave; +gsm0503_mcs7_dl_deinterleave; +gsm0503_mcs8_ul_interleave; +gsm0503_mcs8_ul_deinterleave; +gsm0503_mcs8_dl_interleave; +gsm0503_mcs8_dl_deinterleave; + +gsm0503_xcch_burst_unmap; +gsm0503_xcch_burst_map; +gsm0503_tch_burst_unmap; +gsm0503_tch_burst_map; +gsm0503_mcs5_ul_burst_map; +gsm0503_mcs5_ul_burst_unmap; +gsm0503_mcs7_ul_burst_map; +gsm0503_mcs7_ul_burst_unmap; +gsm0503_mcs5_dl_burst_map; +gsm0503_mcs5_dl_burst_unmap; +gsm0503_mcs7_dl_burst_map; +gsm0503_mcs7_dl_burst_unmap; +gsm0503_mcs5_burst_swap; + +gsm0503_fire_crc40; +gsm0503_cs234_crc16; +gsm0503_mcs_crc8_hdr; +gsm0503_mcs_crc12; +gsm0503_rach_crc6; +gsm0503_sch_crc10; +gsm0503_tch_fr_crc3; +gsm0503_tch_efr_crc8; +gsm0503_amr_crc6; + +gsm0503_egprs_mcs; +gsm0503_xcch_decode; +gsm0503_xcch_encode; +gsm0503_pdtch_decode; +gsm0503_pdtch_egprs_decode; +gsm0503_pdtch_encode; +gsm0503_pdtch_egprs_encode; +gsm0503_tch_fr_decode; +gsm0503_tch_fr_encode; +gsm0503_tch_hr_decode; +gsm0503_tch_hr_encode; +gsm0503_tch_afs_decode; +gsm0503_tch_afs_encode; +gsm0503_tch_ahs_decode; +gsm0503_tch_ahs_encode; +gsm0503_rach_decode; +gsm0503_rach_encode; +gsm0503_sch_decode; +gsm0503_sch_encode; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..7aa5a3c 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -1,7 +1,6 @@ #!/usr/bin/python2 -mod_license = """ -/* +mod_license = """/* * Copyright (C) 2011-2016 Sylvain Munaut * Copyright (C) 2016 sysmocom s.f.m.c. GmbH * @@ -27,7 +26,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, + name = "call-me", description = False, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +50,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -63,8 +68,13 @@ def _state_mask(self): return (1 << (self.k - 1)) - 1 + def combine(self, src, sel, nb): + x = src & sel + fn_xor = lambda x, y: x ^ y + return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) + def next_state(self, state, bit): - nb = combine( + nb = self.combine( (state << 1) | bit, self.poly_divider, self.k, @@ -85,9 +95,10 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -104,9 +115,9 @@ for p_n, p_d in self.polys: if self.recursive and p_d == 1: # Systematic output are replaced when in 'termination' mode - o = combine(src, self.poly_divider, self.k) + o = self.combine(src, self.poly_divider, self.k) else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -121,61 +132,118 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" if len(self.puncture): - print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p - print >>fi, "};" + # Up to 12 numbers should be placed per line + counter = 0 - print >>fi, "\n/* %s */" % self.description - print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, \ + "\nstatic const int %s_puncture[] = {" % self.name + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n};\n") + + # Write description as a multiline comment + if self.description: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Write a final definition + print >>fi, \ + "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k print >>fi, "\t.len = %d," % self.block_len print >>fi, "\t.next_output = %s_output," % self.name print >>fi, "\t.next_state = %s_state," % self.name + if self.recursive: print >>fi, "\t.next_term_output = %s_term_output," % self.name print >>fi, "\t.next_term_state = %s_term_state," % self.name + if len(self.puncture): print >>fi, "\t.puncture = %s_puncture," % self.name + print >>fi, "};" poly = lambda *args: sum([(1 << x) for x in args]) - -def combine(src, sel, nb): - x = src & sel - fn_xor = lambda x, y: x ^ y - return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) # Polynomials according to 3GPP TS 05.03 Annex B G0 = poly(0, 3, 4) @@ -188,307 +256,487 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # RACH definition + ConvolutionalCode( + 14, + CCH_poly, + name = "rach", + description = ["RACH convolutional code"] + ), -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # SCH definition + ConvolutionalCode( + 35, + CCH_poly, + name = "sch", + description = ["SCH convolutional code"] + ), -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), + + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), + + # TCH_FR definition + ConvolutionalCode( + 185, + CCH_poly, + name = "tch_fr", + description = ["TCH/F convolutional code"] + ), + + # TCH_HR definition + ConvolutionalCode( + 98, + [ + ( G4, 1 ), + ( G5, 1 ), + ( G6, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, + 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, + 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214, + 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250, + 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295, + 298, 301, 304, 307, 310, -1, + ], + name = "tch_hr", + description = ["TCH/H convolutional code"] + ), + + # TCH_AHS_7_95 definition + ConvolutionalCode( + 129, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43, + 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95, + 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151, + 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191, + 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221, + 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251, + 255, 257, 259, 261, 263, 265, -1, + ], + name = "tch_ahs_7_95", + description = ["TCH/AHS 7.95 kbits convolutional code"] + ), + + # TCH_AHS_7_4 definition + ConvolutionalCode( + 126, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55, + 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119, + 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, + 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, + 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251, + 253, 255, 257, 259, -1, + ], + name = "tch_ahs_7_4", + description = ["TCH/AHS 7.4 kbits convolutional code"] + ), + + # TCH_AHS_6_7 definition + ConvolutionalCode( + 116, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, + 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189, + 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231, + 233, 235, 237, 239, -1, + ], + name = "tch_ahs_6_7", + description = ["TCH/AHS 6.7 kbits convolutional code"] + ), + + # TCH_AHS_5_9 definition + ConvolutionalCode( + 108, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211, + 215, 219, 221, 223, -1, + ], + name = "tch_ahs_5_9", + description = ["TCH/AHS 5.9 kbits convolutional code"] + ), + + # TCH_AHS_5_15 definition + ConvolutionalCode( + 97, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33, + 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93, + 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159, + 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, + 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, + 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261, + 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289, + 291, 294, 295, 297, 298, 300, 301, -1, + ], + name = "tch_ahs_5_15", + description = ["TCH/AHS 5.15 kbits convolutional code"] + ), + + # TCH_AHS_4_75 definition + ConvolutionalCode( + 89, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34, + 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, + 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166, + 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, + 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256, + 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283, + 284, -1, + ], + name = "tch_ahs_4_75", + description = ["TCH/AHS 4.75 kbits convolutional code"] + ), +] + +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 6 01:43:58 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Tue, 6 Sep 2016 01:43:58 +0000 Subject: [PATCH] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/816 to look at the new patch set (#4). gsm0503: migrate transcoding routines from OsmoBTS The GSM 05.03 transcoding routines are becoming increasingly popular, and some projects (such as GR-GSM and OsmocomBB) also require transcoding capabilities implemented within the libosmocore. Moreover, it would be beeter to clean up the OsmoBTS source code, sharing this code. Currently there are the following data types supported: - xCCH - PDTCH - PDTCH (EDGE) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Also, the conv_gen.py was updated, and now writes a single file. The EDGE MCS convolutional codes are migrated 'as is', i.e. already in generated state. Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a --- M .gitignore M include/Makefile.am M include/osmocom/gsm/gsm0503.h A include/osmocom/gsm/gsm0503_coding.h A include/osmocom/gsm/gsm0503_interleaving.h A include/osmocom/gsm/gsm0503_mapping.h A include/osmocom/gsm/gsm0503_parity.h A include/osmocom/gsm/gsm0503_tables.h M src/gsm/Makefile.am A src/gsm/gsm0503_coding.c A src/gsm/gsm0503_conv_edge.c A src/gsm/gsm0503_interleaving.c A src/gsm/gsm0503_mapping.c A src/gsm/gsm0503_parity.c A src/gsm/gsm0503_tables.c M src/gsm/libosmogsm.map M utils/conv_gen.py 17 files changed, 6,755 insertions(+), 328 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/16/816/4 diff --git a/.gitignore b/.gitignore index 5165364..35f7603 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,8 @@ doc/*.tag src/crc*gen.c -src/gsm/conv*gen.c +src/gsm/gsm6*.c +src/gsm/gsm0503_conv.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/include/Makefile.am b/include/Makefile.am index c125691..6829378 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -69,6 +69,11 @@ osmocom/gsm/gsm0480.h \ osmocom/gsm/gsm0502.h \ osmocom/gsm/gsm0503.h \ + osmocom/gsm/gsm0503_tables.h \ + osmocom/gsm/gsm0503_parity.h \ + osmocom/gsm/gsm0503_mapping.h \ + osmocom/gsm/gsm0503_interleaving.h \ + osmocom/gsm/gsm0503_coding.h \ osmocom/gsm/gsm0808.h \ osmocom/gsm/gsm23003.h \ osmocom/gsm/gsm48.h \ diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index cf1c976..3fda4ce 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -26,7 +26,7 @@ #include -/*! \file conv_gen.h +/*! \file gsm0503.h * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03 */ @@ -36,10 +36,26 @@ */ extern const struct osmo_conv_code gsm0503_xcch; +/*! \brief structure describing convolutional code RACH + */ +extern const struct osmo_conv_code gsm0503_rach; + +/*! \brief structure describing convolutional code SCH + */ +extern const struct osmo_conv_code gsm0503_sch; + /*! \brief structures describing convolutional codes CS2/3 */ extern const struct osmo_conv_code gsm0503_cs2; extern const struct osmo_conv_code gsm0503_cs3; + +/*! \brief structure describing convolutional code TCH/FR + */ +extern const struct osmo_conv_code gsm0503_tch_fr; + +/*! \brief structure describing convolutional code TCH/HR + */ +extern const struct osmo_conv_code gsm0503_tch_hr; /*! \brief structure describing convolutional code TCH/AFS 12.2 */ @@ -72,3 +88,87 @@ /*! \brief structure describing convolutional code TCH/AFS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_afs_4_75; + +/*! \brief structure describing convolutional code TCH/AHS 7.95 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_95; + +/*! \brief structure describing convolutional code TCH/AHS 7.4 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_4; + +/*! \brief structure describing convolutional code TCH/AHS 6.7 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_6_7; + +/*! \brief structure describing convolutional code TCH/AHS 5.9 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_9; + +/*! \brief structure describing convolutional code TCH/AHS 5.15 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_15; + +/*! \brief structure describing convolutional code TCH/AHS 4.75 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; + +/*! \brief structure describing convolutional code EDGE MCS1 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS1 + */ +extern const struct osmo_conv_code gsm0503_mcs1; + +/*! \brief structure describing convolutional code EDGE MCS2 + */ +extern const struct osmo_conv_code gsm0503_mcs2; + +/*! \brief structure describing convolutional code EDGE MCS3 + */ +extern const struct osmo_conv_code gsm0503_mcs3; + +/*! \brief structure describing convolutional code EDGE MCS4 + */ +extern const struct osmo_conv_code gsm0503_mcs4; + +/*! \brief structure describing convolutional code EDGE MCS5 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS5 + */ +extern const struct osmo_conv_code gsm0503_mcs5; + +/*! \brief structure describing convolutional code EDGE MCS6 + */ +extern const struct osmo_conv_code gsm0503_mcs6; + +/*! \brief structure describing convolutional code EDGE MCS7 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS7 + */ +extern const struct osmo_conv_code gsm0503_mcs7; + +/*! \brief structure describing convolutional code EDGE MCS8 + */ +extern const struct osmo_conv_code gsm0503_mcs8; + +/*! \brief structure describing convolutional code EDGE MCS9 + */ +extern const struct osmo_conv_code gsm0503_mcs9; diff --git a/include/osmocom/gsm/gsm0503_coding.h b/include/osmocom/gsm/gsm0503_coding.h new file mode 100644 index 0000000..76f6b7a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_coding.h @@ -0,0 +1,85 @@ +/* + * GSM 05.03 transcoding routines + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +#define GSM0503_GPRS_BURSTS_NBITS (116 * 4) +#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4) + +struct osmo_conv_code; + +enum gsm0503_egprs_mcs { + EGPRS_MCS0, + EGPRS_MCS1, + EGPRS_MCS2, + EGPRS_MCS3, + EGPRS_MCS4, + EGPRS_MCS5, + EGPRS_MCS6, + EGPRS_MCS7, + EGPRS_MCS8, + EGPRS_MCS9, + EGPRS_NUM_MCS, +}; + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len); +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, uint8_t *l2_data, + uint8_t l2_len); +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, + uint16_t nbits, uint8_t *usf_p, int *n_errors, int *n_bits_total); + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int net_order); +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order, + int efr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len); +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total); + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr); +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr); +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic); +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic); + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info); +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst); diff --git a/include/osmocom/gsm/gsm0503_interleaving.h b/include/osmocom/gsm/gsm0503_interleaving.h new file mode 100644 index 0000000..3f477cc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_interleaving.h @@ -0,0 +1,72 @@ +/* + * GSM 05.03 interleaving + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB); + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); diff --git a/include/osmocom/gsm/gsm0503_mapping.h b/include/osmocom/gsm/gsm0503_mapping.h new file mode 100644 index 0000000..74a7b83 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_mapping.h @@ -0,0 +1,55 @@ +/* + * GSM 05.03 mapping + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn); +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn); + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd); +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd); + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs5_burst_swap(sbit_t *eB); diff --git a/include/osmocom/gsm/gsm0503_parity.h b/include/osmocom/gsm/gsm0503_parity.h new file mode 100644 index 0000000..fa8bacc --- /dev/null +++ b/include/osmocom/gsm/gsm0503_parity.h @@ -0,0 +1,35 @@ +/* + * GSM 05.03 parity + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +const struct osmo_crc64gen_code gsm0503_fire_crc40; +const struct osmo_crc16gen_code gsm0503_cs234_crc16; +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr; +const struct osmo_crc16gen_code gsm0503_mcs_crc12; +const struct osmo_crc8gen_code gsm0503_rach_crc6; +const struct osmo_crc16gen_code gsm0503_sch_crc10; +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3; +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8; +const struct osmo_crc8gen_code gsm0503_amr_crc6; diff --git a/include/osmocom/gsm/gsm0503_tables.h b/include/osmocom/gsm/gsm0503_tables.h new file mode 100644 index 0000000..5ab04e5 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_tables.h @@ -0,0 +1,71 @@ +/* + * GSM 05.03 tables + * + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#pragma once + +extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; +extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8]; +extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8]; +extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8]; +extern const ubit_t gsm0503_usf2six[8][6]; +extern const ubit_t gsm0503_usf2twelve_ubit[8][12]; +extern const sbit_t gsm0503_usf2twelve_sbit[8][12]; +extern const uint8_t gsm0503_puncture_cs2[588]; +extern const uint8_t gsm0503_puncture_cs3[676]; +extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108]; +extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117]; +extern const uint8_t gsm0503_puncture_mcs1_p1[588]; +extern const uint8_t gsm0503_puncture_mcs1_p2[588]; +extern const uint8_t gsm0503_puncture_mcs2_p1[732]; +extern const uint8_t gsm0503_puncture_mcs2_p2[732]; +extern const uint8_t gsm0503_puncture_mcs3_p1[948]; +extern const uint8_t gsm0503_puncture_mcs3_p2[948]; +extern const uint8_t gsm0503_puncture_mcs3_p3[948]; +extern const uint8_t gsm0503_puncture_mcs4_p1[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p2[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p3[1116]; +extern const uint8_t gsm0503_puncture_mcs5_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs5_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs6_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs6_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135]; +extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162]; +extern const uint8_t gsm0503_puncture_mcs7_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p3[1404]; +extern const uint8_t gsm0503_puncture_mcs8_p1[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p2[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p3[1692]; +extern const uint8_t gsm0503_puncture_mcs9_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p3[1836]; +extern const uint16_t gsm0503_interleave_mcs5[1248]; +extern const uint8_t gsm0503_gsm_fr_map[76]; +extern const uint8_t gsm0503_gsm_efr_protected_bits[65]; +extern const ubit_t gsm0503_afs_ic_ubit[4][8]; +extern const sbit_t gsm0503_afs_ic_sbit[4][8]; +extern const ubit_t gsm0503_ahs_ic_ubit[4][4]; +extern const sbit_t gsm0503_ahs_ic_sbit[4][4]; +extern const uint8_t gsm0503_tch_hr_interleaving[228][2]; +extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36]; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..13c08d6 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,16 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ + gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ + gsm0503_conv_edge.c gsm0503_tables.c \ + gsm0503_parity.c gsm0503_interleaving.c \ + gsm0503_mapping.c gsm0503_coding.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gprs_gea.c + libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +37,18 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: $(AM_V_GEN)python2 ../../utils/conv_gen.py + +# Some dependencies from libosmocodec +gsm610.c: + $(AM_V_GEN)cp ../codec/gsm610.c ./ + +gsm620.c: + $(AM_V_GEN)cp ../codec/gsm620.c ./ + +gsm660.c: + $(AM_V_GEN)cp ../codec/gsm660.c ./ + +CLEANFILES = gsm0503_conv.c gsm610.c gsm620.c gsm660.c diff --git a/src/gsm/gsm0503_coding.c b/src/gsm/gsm0503_coding.c new file mode 100644 index 0000000..2a91c27 --- /dev/null +++ b/src/gsm/gsm0503_coding.c @@ -0,0 +1,2691 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * EGPRS coding limits + */ + +/* Max header size with parity bits */ +#define EGPRS_HDR_UPP_MAX 54 + +/* Max encoded header size */ +#define EGPRS_HDR_C_MAX 162 + +/* Max punctured header size */ +#define EGPRS_HDR_HC_MAX 160 + +/* Max data block size with parity bits */ +#define EGPRS_DATA_U_MAX 612 + +/* Max encoded data block size */ +#define EGPRS_DATA_C_MAX 1836 + +/* Max single block punctured data size */ +#define EGPRS_DATA_DC_MAX 1248 + +/* Dual block punctured data size */ +#define EGPRS_DATA_C1 612 +#define EGPRS_DATA_C2 EGPRS_DATA_C1 + +/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ +#define GSM_FR_BYTES 33 +/* TS 101318 Chapter 5.2: 112 bits, no sig */ +#define GSM_HR_BYTES 14 +/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ +#define GSM_EFR_BYTES 31 + +struct gsm0503_mcs_code { + uint8_t mcs; + uint8_t usf_len; + + /* Header coding */ + uint8_t hdr_len; + uint8_t hdr_code_len; + uint8_t hdr_punc_len; + const struct osmo_conv_code *hdr_conv; + const uint8_t *hdr_punc; + + /* Data coding */ + uint16_t data_len; + uint16_t data_code_len; + uint16_t data_punc_len; + const struct osmo_conv_code *data_conv; + const uint8_t *data_punc[3]; +}; + +/* + * EGPRS UL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_ul_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +/* + * EGPRS DL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_dl_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +static int osmo_conv_decode_ber(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output, + int *n_errors, int *n_bits_total) +{ + int res, i, coded_len; + ubit_t recoded[EGPRS_DATA_C_MAX]; + + res = osmo_conv_decode(code, input, output); + + if (n_bits_total || n_errors) { + coded_len = osmo_conv_encode(code, output, recoded); + OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len); + } + + /* Count bit errors */ + if (n_errors) { + *n_errors = 0; + for (i = 0; i < coded_len; i++) { + if (! ((recoded[i] && input[i] < 0) || + (!recoded[i] && input[i] > 0)) ) + *n_errors += 1; + } + } + + if (n_bits_total) + *n_bits_total = coded_len; + + return res; +} + + +static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB, + int *n_errors, int *n_bits_total) +{ + ubit_t conv[224]; + int rv; + + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 0; +} + +static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data) +{ + ubit_t conv[224]; + + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + return 0; +} + + +/* + * GSM xCCH block transcoding + */ + +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[456]; + int i; + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL); + + gsm0503_xcch_deinterleave(cB, iB); + + return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total); +} + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data) +{ + ubit_t iB[456], cB[456], hl = 1, hn = 1; + int i; + + _xcch_encode_cB(cB, l2_data); + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn); + + return 0; +} + +/* + * EGPRS PDTCH UL block decoding + */ + +/* + * Type 3 - MCS-1,2,3,4 + * Unmapping and deinterleaving + */ +static int egprs_type3_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t iB[456], q[8]; + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + q + i * 2, q + i * 2 + 1); + } + + gsm0503_mcs1_ul_deinterleave(hc, dc, iB); + + return 0; +} + +/* + * Type 2 - MCS-5,6 + * Unmapping and deinterleaving + */ +static int egprs_type2_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_DC_MAX]; + + for (i=0; i<4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs5_ul_burst_unmap(di, burst, hi, i); + } + + gsm0503_mcs5_ul_deinterleave(hc, dc, hi, di); + + return 0; +} + +/* + * Type 1 - MCS-7,8,9 + * Unmapping and deinterleaving - Note that MCS-7 interleaver is unique + */ +static int egprs_type1_unmap(const sbit_t *bursts, sbit_t *hc, + sbit_t *c1, sbit_t *c2, int msc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_C1 * 2]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs7_ul_burst_unmap(di, burst, hi, i); + } + + if (msc == EGPRS_MCS7) + gsm0503_mcs7_ul_deinterleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_ul_deinterleave(hc, c1, c2, hi, di); + + return 0; +} + +union gprs_rlc_ul_hdr_egprs { + struct gprs_rlc_ul_header_egprs_1 type1; + struct gprs_rlc_ul_header_egprs_2 type2; + struct gprs_rlc_ul_header_egprs_3 type3; +}; + +/* + * Decode EGPRS UL header section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + */ +static int _egprs_decode_hdr(const sbit_t *hc, int mcs, + union gprs_rlc_ul_hdr_egprs *hdr) +{ + sbit_t C[EGPRS_HDR_C_MAX]; + ubit_t upp[EGPRS_HDR_UPP_MAX]; + int i, j, rc; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_ul_codes[mcs]; + + /* Skip depuncturing on MCS-5,6 header */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(C, hc, code->hdr_code_len); + goto hdr_conv_decode; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + i = code->hdr_code_len - 1; + j = code->hdr_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->hdr_punc[i]) + C[i] = hc[j--]; + else + C[i] = 0; + } + +hdr_conv_decode: + osmo_conv_decode_ber(code->hdr_conv, C, upp, NULL, NULL); + rc = osmo_crc8gen_check_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + if (rc) + return -1; + + osmo_ubit2pbit_ext((pbit_t *) hdr, 0, upp, 0, code->hdr_len, 1); + + return 0; +} + +/* + * Blind MCS header decoding based on burst length and CRC validation. + * Ignore 'q' value coding indentification. This approach provides + * the strongest chance of header recovery. + */ +static int egprs_decode_hdr(union gprs_rlc_ul_hdr_egprs *hdr, + const sbit_t *bursts, uint16_t nbits) +{ + int rc; + sbit_t hc[EGPRS_HDR_HC_MAX]; + + if (nbits == GSM0503_GPRS_BURSTS_NBITS) { + /* MCS-1,2,3,4 */ + egprs_type3_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS1, hdr); + if (!rc) + return EGPRS_HDR_TYPE3; + } else if (nbits == GSM0503_EGPRS_BURSTS_NBITS) { + /* MCS-5,6 */ + egprs_type2_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS5, hdr); + if (!rc) + return EGPRS_HDR_TYPE2; + + /* MCS-7,8,9 */ + egprs_type1_unmap(bursts, hc, NULL, NULL, EGPRS_MCS7); + rc = _egprs_decode_hdr(hc, EGPRS_MCS7, hdr); + if (!rc) + return EGPRS_HDR_TYPE1; + } + + return -1; +} + +/* + * Parse EGPRS UL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_ul_cps(struct egprs_cps *cps, + union gprs_rlc_ul_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = (hdr->type2.cps_lo << 2) | hdr->type2.cps_hi; + break; + case EGPRS_HDR_TYPE3: + bits = (hdr->type3.cps_lo << 2) | hdr->type3.cps_hi; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +#define NUM_BYTES(N) ((N + 8 - 1) / 8) + +/* + * Decode EGPRS UL data section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + * 4. Block combining (MCS-7,8,9 only) + */ +static int egprs_decode_data(uint8_t *l2_data, sbit_t *c, + int mcs, int p, int blk, + int *n_errors, int *n_bits_total) +{ + ubit_t u[EGPRS_DATA_U_MAX]; + sbit_t C[EGPRS_DATA_C_MAX]; + + int i, j, rc, data_len; + struct gsm0503_mcs_code *code; + + if (blk && mcs < EGPRS_MCS7) { + /* Invalid MCS-X block state */ + return -1; + } + + code = &gsm0503_mcs_ul_codes[mcs]; + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + /* + * MCS-1,6 - single block processing + * MCS-7,9 - dual block processing + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + i = code->data_code_len - 1; + j = code->data_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->data_punc[p][i]) + C[i] = c[j--]; + else + C[i] = 0; + } + + osmo_conv_decode_ber(code->data_conv, C, u, n_errors, n_bits_total); + rc = osmo_crc16gen_check_bits(&gsm0503_mcs_crc12, u, + data_len, u + data_len); + if (rc) + return -1; + + /* Offsets output pointer on the second block of Type 1 MCS */ + osmo_ubit2pbit_ext(l2_data, code->hdr_len + blk * data_len, + u, 0, data_len, 1); + + /* Return the number of bytes required for the bit message */ + return NUM_BYTES(code->hdr_len + code->data_len); +} + +/* + * Decode EGPRS UL message + * + * 1. Header section decoding + * 2. Extract CPS settings + * 3. Burst unmapping and deinterleaving + * 4. Data section decoding + */ +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, uint16_t nbits, + uint8_t *usf_p, int *n_errors, int *n_bits_total) +{ + sbit_t dc[EGPRS_DATA_DC_MAX]; + sbit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + int type, rc; + struct egprs_cps cps; + union gprs_rlc_ul_hdr_egprs *hdr; + + if ((nbits != GSM0503_GPRS_BURSTS_NBITS) && + (nbits != GSM0503_EGPRS_BURSTS_NBITS)) { + /* Invalid EGPRS bit length */ + return -1; + } + + hdr = (union gprs_rlc_ul_hdr_egprs *) l2_data; + type = egprs_decode_hdr(hdr, bursts, nbits); + if (egprs_parse_ul_cps(&cps, hdr, type) < 0) + return -1; + + switch (cps.mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + egprs_type3_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + egprs_type2_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + egprs_type1_unmap(bursts, NULL, c1, c2, cps.mcs); + break; + default: + /* Invalid MCS-X */ + return -1; + } + + /* Decode MCS-X block, where X = cps.mcs */ + if (cps.mcs < EGPRS_MCS7) { + rc = egprs_decode_data(l2_data, dc, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + } else { + /* MCS-7,8,9 block 1 */ + rc = egprs_decode_data(l2_data, c1, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + + /* MCS-7,8,9 block 2 */ + rc = egprs_decode_data(l2_data, c2, cps.mcs, cps.p[1], + 1, n_errors, n_bits_total); + if (rc < 0) + return -1; + } + + return rc; +} + +/* + * GSM PDTCH block transcoding + */ + +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[676], hl_hn[8]; + ubit_t conv[456]; + int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */ + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j])); + + if (i == 0 || k < best) { + best = k; + cs = i+1; + } + } + + gsm0503_xcch_deinterleave(cB, iB); + + switch (cs) { + case 1: + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 23; + case 2: + for (i = 587, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs2[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs2, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 271, conv + 3 + 271); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1); + + return 34; + case 3: + for (i = 675, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs3[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs3, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 315, conv + 3 + 315); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1); + + return 40; + case 4: + for (i = 12; i < 456; i++) + conv[i] = (cB[i] < 0) ? 1 : 0; + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 12; j++) + k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[9] = usf & 1; + conv[10] = (usf >> 1) & 1; + conv[11] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 9, 431, conv + 9 + 431); + if (rv) { + *n_bits_total = 456 - 12; + *n_errors = *n_bits_total; + return -1; + } + + *n_bits_total = 456 - 12; + *n_errors = 0; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1); + + return 54; + default: + *n_bits_total = 0; + *n_errors = 0; + break; + } + + return -1; +} + +/* + * EGPRS PDTCH UL block encoding + */ +static int egprs_type3_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + ubit_t iB[456]; + const ubit_t *hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + gsm0503_mcs1_dl_interleave(gsm0503_usf2six[usf], hc, dc, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return 0; +} + +static int egprs_type2_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_DC_MAX]; + + gsm0503_mcs5_dl_interleave(hc, dc, hi, di); + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs5_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_type1_map(ubit_t *bursts, ubit_t *hc, + ubit_t *c1, ubit_t *c2, int usf, int mcs) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_C1 * 2]; + + if (mcs == EGPRS_MCS7) + gsm0503_mcs7_dl_interleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_dl_interleave(hc, c1, c2, hi, di); + + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs7_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_encode_hdr(ubit_t *hc, uint8_t *l2_data, int mcs) +{ + int i, j; + ubit_t upp[EGPRS_HDR_UPP_MAX], C[EGPRS_HDR_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + osmo_pbit2ubit_ext(upp, 0, l2_data, code->usf_len, code->hdr_len, 1); + osmo_crc8gen_set_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + + osmo_conv_encode(code->hdr_conv, upp, C); + + /* MCS-5,6 header direct puncture instead of table */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(hc, C, code->hdr_code_len); + hc[99] = hc[98]; + return 0; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->hdr_code_len; i++) { + if (!code->hdr_punc[i]) + hc[j++] = C[i]; + } + + return 0; +} + +static int egprs_encode_data(ubit_t *c, uint8_t *l2_data, + int mcs, int p, int blk) +{ + int i, j, data_len; + ubit_t u[EGPRS_DATA_U_MAX], C[EGPRS_DATA_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + /* + * Dual block - MCS-7,8,9 + * Single block - MCS-1,2,3,4,5,6 + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + osmo_pbit2ubit_ext(u, 0, l2_data, + code->usf_len + code->hdr_len + blk * data_len, data_len, 1); + + osmo_crc16gen_set_bits(&gsm0503_mcs_crc12, u, data_len, u + data_len); + + osmo_conv_encode(code->data_conv, u, C); + + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->data_code_len; i++) { + if (!code->data_punc[p][i]) + c[j++] = C[i]; + } + + return 0; +} + +union gprs_rlc_dl_hdr_egprs { + struct gprs_rlc_dl_header_egprs_1 type1; + struct gprs_rlc_dl_header_egprs_2 type2; + struct gprs_rlc_dl_header_egprs_3 type3; +}; + +/* + * Parse EGPRS DL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_dl_cps(struct egprs_cps *cps, + union gprs_rlc_dl_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = hdr->type2.cps; + break; + case EGPRS_HDR_TYPE3: + bits = hdr->type3.cps; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * EGPRS DL message encoding + */ +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, + uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t hc[EGPRS_DATA_C_MAX], dc[EGPRS_DATA_DC_MAX]; + ubit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + uint8_t mcs; + struct egprs_cps cps; + union gprs_rlc_dl_hdr_egprs *hdr; + + switch (l2_len) { + case 27: + mcs = EGPRS_MCS1; + break; + case 33: + mcs = EGPRS_MCS2; + break; + case 42: + mcs = EGPRS_MCS3; + break; + case 49: + mcs = EGPRS_MCS4; + break; + case 60: + mcs = EGPRS_MCS5; + break; + case 78: + mcs = EGPRS_MCS6; + break; + case 118: + mcs = EGPRS_MCS7; + break; + case 142: + mcs = EGPRS_MCS8; + break; + case 154: + mcs = EGPRS_MCS9; + break; + default: + return -1; + } + + /* Read header for USF and puncturing matrix selection. */ + hdr = (union gprs_rlc_dl_hdr_egprs *) l2_data; + + switch (mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + /* Check for valid CPS and matching MCS to message size */ + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE3) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type3_map(bursts, hc, dc, hdr->type3.usf); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE2) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type2_map(bursts, hc, dc, hdr->type2.usf); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE1) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(c1, l2_data, mcs, cps.p[0], 0); + egprs_encode_data(c2, l2_data, mcs, cps.p[1], 1); + egprs_type1_map(bursts, hc, c1, c2, hdr->type1.usf, mcs); + break; + } + + return mcs >= EGPRS_MCS5 ? GSM0503_EGPRS_BURSTS_NBITS : + GSM0503_GPRS_BURSTS_NBITS; + +bad_header: + /* Invalid EGPRS MCS-X header */ + return -1; +} + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t iB[456], cB[676]; + const ubit_t *hl_hn; + ubit_t conv[334]; + int i, j, usf; + + switch (l2_len) { + case 23: + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[0]; + + break; + case 34: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 271, conv + 3 + 271); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs2, conv, cB); + + for (i = 0, j = 0; i < 588; i++) + if (!gsm0503_puncture_cs2[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[1]; + + break; + case 40: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 315, conv + 3 + 315); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs3, conv, cB); + + for (i = 0, j = 0; i < 676; i++) + if (!gsm0503_puncture_cs3[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[2]; + + break; + case 54: + osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9, + 431, cB + 9 + 431); + + memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + break; + default: + return -1; + } + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return GSM0503_GPRS_BURSTS_NBITS; +} + + +/* + * GSM TCH/F FR/EFR transcoding + */ + +static void tch_fr_reassemble(uint8_t *tch_data, + ubit_t *b_bits, int net_order) +{ + int i, j, k, l, o; + + tch_data[0] = 0xd << 4; + memset(tch_data + 1, 0, 32); + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); + + return; + } + + /* reassemble d-bits */ + i = 0; /* counts bits */ + j = 4; /* counts output bits */ + k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset input bits */ + while (i < 260) { + tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7))); + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l]-1; + } + i++; + j++; + } +} + +static void tch_fr_disassemble(ubit_t *b_bits, + uint8_t *tch_data, int net_order) +{ + int i, j, k, l, o; + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + + return; + } + + i = 0; /* counts bits */ + j = 4; /* counts input bits */ + k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset output bits */ + while (i < 260) { + b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l] - 1; + } + i++; + j++; + } +} + +static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0x00; /* F = 0, FT = 000 */ + memset(tch_data + 1, 0, 14); + + for (i = 0, j = 8; i < 112; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 8; i < 112; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0xc << 4; + memset(tch_data + 1, 0, 30); + + for (i = 0, j = 4; i < 244; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 4; i < 244; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len) +{ + int i, j; + + memset(tch_data, 0, (len + 7) >> 3); + + for (i = 0, j = 0; i < len; i++, j++) + tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7))); +} + +static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len) +{ + int i, j; + + for (i = 0, j = 0; i < len; i++, j++) + d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm610_bitorder[i]] = d_bits[i]; +} + +static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm610_bitorder[i]]; +} + +static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + const uint16_t *map; + + if (!b_bits[34] && !b_bits[35]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + d_bits[i] = b_bits[map[i]]; +} + +static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm660_bitorder[i]] = d_bits[i]; +} + +static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm660_bitorder[i]]; +} + +static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 65; i++) + b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1]; +} + +static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + int i; + + for (i = 0; i < 91; i++) { + d[i << 1] = u[i]; + d[(i << 1) + 1] = u[184 - i]; + } + + for (i = 0; i < 3; i++) + p[i] = u[91 + i]; +} + +static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + int i; + + for (i = 0; i < 91; i++) { + u[i] = d[i << 1]; + u[184 - i] = d[(i << 1) + 1]; + } + + for (i = 0; i < 3; i++) + u[91 + i] = p[i]; +} + +static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + memcpy(d, u, 95); + memcpy(p, u + 95, 3); +} + +static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + memcpy(u, d, 95); + memcpy(u + 95, p, 3); +} + +static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p) +{ + memcpy(w, s, 71); + w[71] = w[72] = s[69]; + memcpy(w + 73, s + 71, 50); + w[123] = w[124] = s[119]; + memcpy(w + 125, s + 121, 53); + w[178] = w[179] = s[172]; + memcpy(w + 180, s + 174, 50); + w[230] = w[231] = s[222]; + memcpy(w + 232, s + 224, 20); + memcpy(w + 252, p, 8); +} + +static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w) +{ + int sum; + + memcpy(s, w, 71); + sum = s[69] + w[71] + w[72]; + s[69] = (sum > 2); + memcpy(s + 71, w + 73, 50); + sum = s[119] + w[123] + w[124]; + s[119] = (sum > 2); + memcpy(s + 121, w + 125, 53); + sum = s[172] + w[178] + w[179]; + s[172] = (sum > 2); + memcpy(s + 174, w + 180, 50); + sum = s[220] + w[230] + w[231]; + s[222] = (sum > 2); + memcpy(s + 224, w + 232, 20); + memcpy(p, w + 252, 8); +} + +static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot) +{ + memcpy(u, d, prot); + memcpy(u + prot, p, 6); + memcpy(u + prot + 6, d + prot, len - prot); +} + +static void tch_amr_unmerge(ubit_t *d, ubit_t *p, + ubit_t *u, int len, int prot) +{ + memcpy(d, u, prot); + memcpy(p, u+prot, 6); + memcpy(d + prot, u + prot + 6, len - prot); +} + +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, + int net_order, int efr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[185], s[244], w[260], b[65], d[260], p[8]; + int i, rv, len, steal = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return 23; + } + + osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total); + + tch_fr_unreorder(d, p, conv); + + for (i = 0; i < 78; i++) + d[i + 182] = (cB[i + 378] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p); + if (rv) { + /* Error checking CRC8 for the FR part of an EFR/FR frame */ + return -1; + } + + if (efr) { + tch_efr_d_to_w(w, d); + + tch_efr_unreorder(s, p, w); + + tch_efr_protected(s, b); + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p); + if (rv) { + /* Error checking CRC8 for the EFR part of an EFR frame */ + return -1; + } + + tch_efr_reassemble(tch_data, s); + + len = GSM_EFR_BYTES; + } else { + tch_fr_d_to_b(w, d); + + tch_fr_reassemble(tch_data, w, net_order); + + len = GSM_FR_BYTES; + } + + return len; +} + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, + int len, int net_order) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[185], w[260], b[65], s[244], d[260], p[8]; + int i; + + switch (len) { + case GSM_EFR_BYTES: /* TCH EFR */ + + tch_efr_disassemble(s, tch_data); + + tch_efr_protected(s, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p); + + tch_efr_reorder(w, s, p); + + tch_efr_w_to_d(d, w); + + goto coding_efr_fr; + case GSM_FR_BYTES: /* TCH FR */ + tch_fr_disassemble(w, tch_data, net_order); + + tch_fr_b_to_d(d, w); + +coding_efr_fr: + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p); + + tch_fr_reorder(conv, d, p); + + memcpy(cB + 378, d + 182, 78); + + osmo_conv_encode(&gsm0503_tch_fr, conv, cB); + + h = 0; + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + break; + default: + return -1; + } + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; +} + +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i, rv, steal = 0; + + /* Only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* If we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total); + + tch_hr_unreorder(d, p, conv); + + for (i = 0; i < 17; i++) + d[i + 95] = (cB[i + 211] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + if (rv) { + /* Error checking CRC8 for an HR frame */ + return -1; + } + + tch_hr_d_to_b(b, d); + + tch_hr_reassemble(tch_data, b); + + return 15; +} + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i; + + switch (len) { + case 15: /* TCH HR */ + tch_hr_disassemble(b, tch_data); + + tch_hr_b_to_d(d, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + + tch_hr_reorder(conv, d, p); + + osmo_conv_encode(&gsm0503_tch_hr, conv, cB); + + memcpy(cB + 211, d + 95, 17); + + h = 0; + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 1); + } + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i=0; i<6; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + for (i=2; i<4; i++) { + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + } + + break; + default: + return -1; + } + + return 0; +} + +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + *n_errors = 0; *n_bits_total = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 7: /* TCH/AFS12.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 244, 81); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p); + if (rv) { + /* Error checking CRC8 for an AMR 12.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 244); + + len = 31; + + break; + case 6: /* TCH/AFS10.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 204, 65); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p); + if (rv) { + /* Error checking CRC8 for an AMR 10.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 204); + + len = 26; + + break; + case 5: /* TCH/AFS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 159, 75); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AFS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 148, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AFS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 134, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AFS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 118, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AFS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 103, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AFS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 95, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 448; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + goto facch; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID is not in codec list! */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID is not in codec list! */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 7: /* TCH/AFS12.2 */ + if (len != 31) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 244); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p); + + tch_amr_merge(conv, d, p, 244, 81); + + osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8); + + break; + case 6: /* TCH/AFS10.2 */ + if (len != 26) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 204); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p); + + tch_amr_merge(conv, d, p, 204, 65); + + osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8); + + break; + case 5: /* TCH/AFS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p); + + tch_amr_merge(conv, d, p, 159, 75); + + osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8); + + break; + case 4: /* TCH/AFS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 148, 61); + + osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8); + + break; + case 3: /* TCH/AFS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 134, 55); + + osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8); + + break; + case 2: /* TCH/AFS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 118, 55); + + osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8); + + break; + case 1: /* TCH/AFS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 103, 49); + + osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8); + + break; + case 0: /* TCH/AFS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 95, 39); + + osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 8); + +facch: + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + + /* only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* if we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 4; j++) + k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 5: /* TCH/AHS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 123, 67); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + for (i = 0; i < 36; i++) + d[i + 123] = (cB[i + 192] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AHS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 120, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + for (i = 0; i < 28; i++) + d[i + 120] = (cB[i + 200] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AHS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 110, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + for (i = 0; i < 24; i++) + d[i + 110] = (cB[i + 204] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AHS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 102, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + for (i = 0; i < 16; i++) + d[i + 102] = (cB[i + 212] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AHS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 91, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 91] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AHS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 83, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 83] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 159; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 6; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], + &h, i >> 2); + for (i = 2; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + + return 0; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID %d not in codec list */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID %d not in codec list */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 5: /* TCH/AHS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p); + + tch_amr_merge(conv, d, p, 123, 67); + + osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4); + + memcpy(cB + 192, d + 123, 36); + + break; + case 4: /* TCH/AHS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 120, 61); + + osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4); + + memcpy(cB + 200, d + 120, 28); + + break; + case 3: /* TCH/AHS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 110, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4); + + memcpy(cB + 204, d + 110, 24); + + break; + case 2: /* TCH/AHS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 102, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4); + + memcpy(cB + 212, d + 102, 16); + + break; + case 1: /* TCH/AHS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 91, 49); + + osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4); + + memcpy(cB + 216, d + 91, 12); + + break; + case 0: /* TCH/AHS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 83, 39); + + osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4); + + memcpy(cB + 216, d + 83, 12); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 4); + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1); + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +/* + * GSM RACH transcoding + */ + +/* + * GSM RACH apply BSIC to parity + * + * p(j) = p(j) xor b(j) j = 0, ..., 5 + * b(0) = MSB of PLMN colour code + * b(5) = LSB of BS colour code + */ + +static int rach_apply_bsic(ubit_t *d, uint8_t bsic) +{ + int i; + + /* Apply it */ + for (i = 0; i < 6; i++) + d[8 + i] ^= ((bsic >> (5 - i)) & 1); + + return 0; +} + +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic) +{ + ubit_t conv[14]; + int rv; + + osmo_conv_decode(&gsm0503_rach, burst, conv); + + rach_apply_bsic(conv, bsic); + + rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + if (rv) + return -1; + + osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1); + + return 0; +} + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic) +{ + ubit_t conv[14]; + + osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1); + + osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + + rach_apply_bsic(conv, bsic); + + osmo_conv_encode(&gsm0503_rach, conv, burst); + + return 0; +} + + +/* + * GSM SCH transcoding + */ + +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst) +{ + ubit_t conv[35]; + int rv; + + osmo_conv_decode(&gsm0503_sch, burst, conv); + + rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + if (rv) + return -1; + + osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1); + + return 0; +} + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info) +{ + ubit_t conv[35]; + + osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1); + + osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + + osmo_conv_encode(&gsm0503_sch, conv, burst); + + return 0; +} diff --git a/src/gsm/gsm0503_conv_edge.c b/src/gsm/gsm0503_conv_edge.c new file mode 100644 index 0000000..a542323 --- /dev/null +++ b/src/gsm/gsm0503_conv_edge.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2016 Tom Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +static const uint8_t conv_mcs_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 }, + { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 }, + { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 }, + { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 }, + { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, + { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 }, +}; + +static const uint8_t conv_mcs_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, +}; + + +const struct osmo_conv_code gsm0503_mcs1_dl_hdr = { + .N = 3, + .K = 7, + .len = 36, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1_ul_hdr = { + .N = 3, + .K = 7, + .len = 39, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs1 = { + .N = 3, + .K = 7, + .len = 190, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs2 = { + .N = 3, + .K = 7, + .len = 238, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs3 = { + .N = 3, + .K = 7, + .len = 310, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs4 = { + .N = 3, + .K = 7, + .len = 366, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_dl_hdr = { + .N = 3, + .K = 7, + .len = 33, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5_ul_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs5 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs6 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_dl_hdr = { + .N = 3, + .K = 7, + .len = 45, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7_ul_hdr = { + .N = 3, + .K = 7, + .len = 54, + .term = CONV_TERM_TAIL_BITING, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs7 = { + .N = 3, + .K = 7, + .len = 462, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs8 = { + .N = 3, + .K = 7, + .len = 558, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; + +const struct osmo_conv_code gsm0503_mcs9 = { + .N = 3, + .K = 7, + .len = 606, + .next_output = conv_mcs_next_output, + .next_state = conv_mcs_next_state, +}; diff --git a/src/gsm/gsm0503_interleaving.c b/src/gsm/gsm0503_interleaving.c new file mode 100644 index 0000000..0c1b8a0 --- /dev/null +++ b/src/gsm/gsm0503_interleaving.c @@ -0,0 +1,574 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include +#include + +/* + * GSM xCCH interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 4 blocks of 114 bits: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 4) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (u) { + for (k=0; k<12; k++) + u[k] = c[k]; + } + + if (hc) { + for (k=12; k<80; k++) + hc[k - 12] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<12; k++) + c[k] = up[k]; + for (k=12; k<80; k++) + c[k] = hc[k - 12]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k=0; k<25; k++) + c[k] = cp[k]; + for (k=26; k<82; k++) + c[k - 1] = cp[k]; + for (k=83; k<139; k++) + c[k - 2] = cp[k]; + for (k=140; k<424; k++) + c[k - 3] = cp[k]; + for (k=425; k<456; k++) + c[k - 4] = cp[k]; + + if (hc) { + for (k=0; k<80; k++) + hc[k] = c[k]; + } + + if (dc) { + for (k=80; k<452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k=0; k<80; k++) + c[k] = hc[k]; + for (k=80; k<452; k++) + c[k] = dc[k - 80]; + + for (k=0; k<25; k++) + cp[k] = c[k]; + for (k=26; k<82; k++) + cp[k] = c[k - 1]; + for (k=83; k<139; k++) + cp[k] = c[k - 2]; + for (k=140; k<424; k++) + cp[k] = c[k - 3]; + for (k=425; k<456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hi[j] = hc[k]; + } + + /* Data */ + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k=0; k<100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k=0; k<1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k=0; k<124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k=0; k<1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +/* + * GSM TCH FR/EFR/AFS interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 8 blocks of 114 bits, + * where even bits of the first 4 blocks and odd bits of the last 4 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 8) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +/* + * GSM TCH HR/AHS interleaving and burst mapping + * + * Interleaving: + * + * Given 288 coded input bits, form 4 blocks of 114 bits, + * where even bits of the first 2 blocks and odd bits of the last 2 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 227 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 2n + b + * j, b = table[k]; + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k=0; k<228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + iB[B * 114 + j] = cB[k]; + } +} + diff --git a/src/gsm/gsm0503_mapping.c b/src/gsm/gsm0503_mapping.c new file mode 100644 index 0000000..c2079b9 --- /dev/null +++ b/src/gsm/gsm0503_mapping.c @@ -0,0 +1,291 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn) +{ + memcpy(iB, eB, 57); + memcpy(iB+57, eB+59, 57); + + if (hl) + *hl = eB[57]; + + if (hn) + *hn = eB[58]; +} + +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn) +{ + memcpy(eB, iB, 57); + memcpy(eB+59, iB+57, 57); + + if (hl) + eB[57] = *hl; + if (hn) + eB[58] = *hn; +} + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (iB) { + for (i=odd; i<57; i+=2) + iB[i] = eB[i]; + for (i=58-odd; i<114; i+=2) + iB[i] = eB[i+2]; + } + + if (h) { + if (!odd) + *h = eB[58]; + else + *h = eB[57]; + } +} + +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (eB) { + for (i=odd; i<57; i+=2) + eB[i] = iB[i]; + for (i=58-odd; i<114; i+=2) + eB[i+2] = iB[i]; + } + + if (h) { + if (!odd) + eB[58] = *h; + else + eB[57] = *h; + } +} + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<168; j++) + eB[j] = hi[25*B+j-156]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<192; j++) + eB[j] = hi[25*B+j-167]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<168; j++) + hi[25*B+j-156] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<192; j++) + hi[25*B+j-167] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + eB[j] = di[312*B+j]; + for (j=156; j<174; j++) + eB[j] = hi[34*B+j-156]; + for (j=174; j<176; j++) + eB[j] = 0; + for (j=176; j<192; j++) + eB[j] = hi[34*B+j-158]; + for (j=192; j<348; j++) + eB[j] = di[312*B+j-36]; +} + +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<156; j++) + di[312*B+j] = eB[j]; + for (j=156; j<174; j++) + hi[34*B+j-156] = eB[j]; + for (j=176; j<192; j++) + hi[34*B+j-158] = eB[j]; + for (j=192; j<348; j++) + di[312*B+j-36] = eB[j]; +} + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<168; j++) + eB[j] = hi[31*B+j-153]; + for (j=168; j<174; j++) + eB[j] = up[9*B+j-168]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<179; j++) + eB[j] = up[9*B+j-170]; + for (j=179; j<195; j++) + eB[j] = hi[31*B+j-164]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<168; j++) + hi[31*B+j-153] = eB[j]; + for (j=168; j<174; j++) + up[9*B+j-168] = eB[j]; + + for (j=176; j<179; j++) + up[9*B+j-170] = eB[j]; + for (j=179; j<195; j++) + hi[31*B+j-164] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j=0; j<153; j++) + eB[j] = di[306*B+j]; + for (j=153; j<174; j++) + eB[j] = hi[40*B+j-153]; + for (j=174; j<176; j++) + eB[j] = q[2*B+j-174]; + for (j=176; j<195; j++) + eB[j] = hi[40*B+j-155]; + for (j=195; j<348; j++) + eB[j] = di[306*B+j-42]; +} + +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j=0; j<153; j++) + di[306*B+j] = eB[j]; + for (j=153; j<174; j++) + hi[40*B+j-153] = eB[j]; + + for (j=176; j<195; j++) + hi[40*B+j-155] = eB[j]; + for (j=195; j<348; j++) + di[306*B+j-42] = eB[j]; +} + +void gsm0503_mcs5_burst_swap(sbit_t *eB) +{ + sbit_t t[14]; + + t[0] = eB[155]; + t[1] = eB[158]; + t[2] = eB[161]; + t[3] = eB[164]; + t[4] = eB[167]; + t[5] = eB[170]; + t[6] = eB[173]; + t[7] = eB[195]; + t[8] = eB[196]; + t[9] = eB[198]; + t[10] = eB[199]; + t[11] = eB[201]; + t[12] = eB[202]; + t[13] = eB[204]; + + eB[155] = eB[142]; + eB[158] = eB[144]; + eB[161] = eB[145]; + eB[164] = eB[147]; + eB[167] = eB[148]; + eB[170] = eB[150]; + eB[173] = eB[151]; + eB[195] = eB[176]; + eB[196] = eB[179]; + eB[198] = eB[182]; + eB[199] = eB[185]; + eB[201] = eB[188]; + eB[202] = eB[191]; + eB[204] = eB[194]; + + eB[142] = t[0]; + eB[144] = t[1]; + eB[145] = t[2]; + eB[147] = t[3]; + eB[148] = t[4]; + eB[150] = t[5]; + eB[151] = t[6]; + eB[176] = t[7]; + eB[179] = t[8]; + eB[182] = t[9]; + eB[185] = t[10]; + eB[188] = t[11]; + eB[191] = t[12]; + eB[194] = t[13]; +} diff --git a/src/gsm/gsm0503_parity.c b/src/gsm/gsm0503_parity.c new file mode 100644 index 0000000..c9cfba4 --- /dev/null +++ b/src/gsm/gsm0503_parity.c @@ -0,0 +1,145 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +/* + * GSM (SACCH) parity (FIRE code) + * + * g(x) = (x^23 + 1)(x^17 + x^3 + 1) + * = x^40 + x^26 + x^23 + x^17 + x^3 + a1 + */ + +const struct osmo_crc64gen_code gsm0503_fire_crc40 = { + .bits = 40, + .poly = 0x0004820009ULL, + .init = 0x0000000000ULL, + .remainder = 0xffffffffffULL, +}; + + +/* + * GSM PDTCH CS-2, CS-3, CS-4 parity + * + * g(x) = x^16 + x^12 + x^5 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_cs234_crc16 = { + .bits = 16, + .poly = 0x1021, + .init = 0x0000, + .remainder = 0xffff, +}; + +/* + * EDGE MCS header parity + * + */ + +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = { + .bits = 8, + .poly = 0x49, + .init = 0x00, + .remainder = 0xff, +}; + +/* + * EDGE MCS data parity + * + */ + +const struct osmo_crc16gen_code gsm0503_mcs_crc12 = { + .bits = 12, + .poly = 0x0d31, + .init = 0x0000, + .remainder = 0x0fff, +}; + +/* + * GSM RACH parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_rach_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + + +/* + * GSM SCH parity + * + * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1 + */ + +const struct osmo_crc16gen_code gsm0503_sch_crc10 = { + .bits = 10, + .poly = 0x175, + .init = 0x000, + .remainder = 0x3ff, +}; + + +/* + * GSM TCH FR/HR/EFR parity + * + * g(x) = x^3 + x + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = { + .bits = 3, + .poly = 0x3, + .init = 0x0, + .remainder = 0x7, +}; + +/* + * GSM TCH EFR parity + * + * g(x) = x^8 + x^4 + x^3 + x^2 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = { + .bits = 8, + .poly = 0x1d, + .init = 0x00, + .remainder = 0x00, +}; + +/* + * GSM AMR parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ + +const struct osmo_crc8gen_code gsm0503_amr_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + diff --git a/src/gsm/gsm0503_tables.c b/src/gsm/gsm0503_tables.c new file mode 100644 index 0000000..95132b1 --- /dev/null +++ b/src/gsm/gsm0503_tables.c @@ -0,0 +1,1732 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = { + { 1,1, 1,1, 1,1, 1,1 }, + { 1,1, 0,0, 1,0, 0,0 }, + { 0,0, 1,0, 0,0, 0,1 }, + { 0,0, 0,1, 0,1, 1,0 }, +}; + +const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = { + { 0,0, 0,1, 0,1, 1,0 }, + { 0,0, 0,0, 0,0, 0,0 }, + { 1,1, 1,0, 0,1, 1,1 }, +}; + +const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = { + { -127,-127, -127,-127, -127,-127, -127,-127 }, + { -127,-127, 127, 127, -127, 127, 127, 127 }, + { 127, 127, -127, 127, 127, 127, 127,-127 }, + { 127, 127, 127,-127, 127,-127, -127, 127 }, +}; + +const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = { + { 127, 127, 127,-127, 127,-127, -127, 127 }, + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, -127, 127, 127,-127, -127,-127 }, +}; + +const ubit_t gsm0503_usf2six[8][6] = { + { 0,0,0, 0,0,0 }, + { 1,0,0, 1,0,1 }, + { 0,1,0, 1,1,0 }, + { 1,1,0, 0,1,1 }, + { 0,0,1, 0,1,1 }, + { 1,0,1, 1,1,0 }, + { 0,1,1, 1,0,1 }, + { 1,1,1, 0,0,0 }, +}; + +const ubit_t gsm0503_usf2twelve_ubit[8][12] = { + { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }, + { 1,1,0, 1,0,0, 0,0,1, 0,1,1 }, + { 0,0,1, 1,0,1, 1,1,0, 1,1,0 }, + { 1,1,1, 0,0,1, 1,1,1, 1,0,1 }, + { 0,0,0, 0,1,1, 0,1,1, 1,0,1 }, + { 1,1,0, 1,1,1, 0,1,0, 1,1,0 }, + { 0,0,1, 1,1,0, 1,0,1, 0,1,1 }, + { 1,1,1, 0,1,0, 1,0,0, 0,0,0 }, +}; + +const sbit_t gsm0503_usf2twelve_sbit[8][12] = { + { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 }, + { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 }, + { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 }, + { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 }, + { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 }, + { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 }, + { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 }, +}; + +const uint8_t gsm0503_puncture_cs2[588] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1 +}; + +const uint8_t gsm0503_puncture_cs3[676] = { + 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0 +}; + +const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = { + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p1[588] = { + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p2[588] = { + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p1[732] = { + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p2[732] = { + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p1[948] = { + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p2[948] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p3[948] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs4_p1[1116] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p2[1116] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p3[1116] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs5_p1[1404] = { + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs5_p2[1404] = { + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs6_p1[1836] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs6_p2[1836] = { + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0, + 0,1,0,0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p1[1404] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs7_p2[1404] = { + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p3[1404] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p1[1692] = { + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs8_p2[1692] = { + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p3[1692] = { + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p1[1836] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p2[1836] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p3[1836] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, +}; + +const uint16_t gsm0503_interleave_mcs5[1248] = { + 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428, + 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968, + 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575, + 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688, + 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440, + 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980, + 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942, + 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700, + 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452, + 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414, + 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954, + 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712, + 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101, + 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420, + 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960, + 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567, + 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695, + 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432, + 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972, + 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937, + 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707, + 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444, + 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409, + 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949, + 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719, + 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096, + 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427, + 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967, + 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574, + 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687, + 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439, + 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979, + 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944, + 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699, + 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451, + 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416, + 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956, + 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711, + 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103, + 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422, + 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962, + 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569, + 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694, + 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434, + 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974, + 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936, + 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706, + 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446, + 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408, + 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948, + 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718, + 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095, + 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426, + 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966, + 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573, + 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689, + 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438, + 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978, + 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943, + 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701, + 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450, + 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415, + 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955, + 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713, + 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102, + 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421, + 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961, + 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568, + 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693, + 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433, + 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973, + 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938, + 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705, + 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445, + 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410, + 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950, + 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717, + 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097, +}; + +/* this corresponds to the bit-lengths of the individual codec + * parameters as indicated in Table 1.1 of TS 06.10 */ +const uint8_t gsm0503_gsm_fr_map[76] = { + 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* this table describes the 65 most importaint bits from EFR coded + * bits as indicated in TS 05.03 (3.1.1.1) */ +const uint8_t gsm0503_gsm_efr_protected_bits[65] = { + 39, 40, 41, 42, 43, 44, 48, 87, 45, 2, + 3, 8, 10, 18, 19, 24, 46, 47,142,143, + 144,145,146,147, 92, 93,195,196, 98,137, + 148, 94,197,149,150, 95,198, 4, 5, 11, + 12, 16, 9, 6, 7, 13, 17, 20, 96,199, + 1, 14, 15, 21, 25, 26, 28,151,201,190, + 240, 88,138,191,241 +}; + +/* Encoded in-band data for speech frames */ +const ubit_t gsm0503_afs_ic_ubit[4][8] = { + { 0,0,0,0,0,0,0,0 }, + { 0,1,0,1,1,1,0,1 }, + { 1,0,1,1,1,0,1,0 }, + { 1,1,1,0,0,1,1,1 }, +}; + +const sbit_t gsm0503_afs_ic_sbit[4][8] = { + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { 127,-127, 127,-127,-127,-127, 127,-127 }, + { -127, 127,-127,-127,-127, 127,-127, 127 }, + { -127,-127,-127, 127, 127,-127,-127,-127 }, +}; + +const ubit_t gsm0503_ahs_ic_ubit[4][4] = { + { 0,0,0,0 }, + { 1,0,0,1 }, + { 1,1,1,0 }, + { 0,1,1,1 }, +}; + +const sbit_t gsm0503_ahs_ic_sbit[4][4] = { + { 127, 127, 127, 127 }, + { -127, 127, 127,-127 }, + { -127,-127,-127, 127 }, + { 127,-127,-127,-127 }, +}; + +const uint8_t gsm0503_tch_hr_interleaving[228][2] = { + { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 }, + { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 }, + { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 }, + { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 }, + { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 }, + { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 }, + { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 }, + { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 }, + { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 }, + { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 }, + { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 }, + { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 }, + { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 }, + { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 }, + { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 }, + { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 }, + { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 }, + { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 }, + { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 }, + { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 }, + { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 }, + { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 }, + { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 }, + { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 }, + { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 }, + { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 }, + { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 }, + { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 }, + { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 }, + { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 }, + { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 }, + { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 }, + { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 }, + { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 }, + { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 }, + { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 }, + { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 }, + { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 }, +}; + +/* + * 3GPP TS 05.03 5.1.9.1.2 "USF precoding" + */ +const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = { + { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, }, + { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, }, + { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, }, + { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, }, + { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, }, + { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, }, + { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, }, + { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, }, +}; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index dc8559f..1bde75d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -71,8 +71,12 @@ gsm0502_calc_paging_group; gsm0503_xcch; +gsm0503_rach; +gsm0503_sch; gsm0503_cs2; gsm0503_cs3; +gsm0503_tch_fr; +gsm0503_tch_hr; gsm0503_tch_afs_12_2; gsm0503_tch_afs_10_2; gsm0503_tch_afs_7_95; @@ -81,6 +85,124 @@ gsm0503_tch_afs_5_9; gsm0503_tch_afs_5_15; gsm0503_tch_afs_4_75; +gsm0503_tch_ahs_7_95; +gsm0503_tch_ahs_7_4; +gsm0503_tch_ahs_6_7; +gsm0503_tch_ahs_5_9; +gsm0503_tch_ahs_5_15; +gsm0503_tch_ahs_4_75; +gsm0503_pdtch_hl_hn_ubit; +gsm0503_pdtch_edge_hl_hn_ubit; +gsm0503_pdtch_hl_hn_sbit; +gsm0503_pdtch_edge_hl_hn_sbit; +gsm0503_usf2six; +gsm0503_usf2twelve_ubit; +gsm0503_usf2twelve_sbit; +gsm0503_puncture_cs2; +gsm0503_puncture_cs3; +gsm0503_puncture_mcs1_dl_hdr; +gsm0503_puncture_mcs1_ul_hdr; +gsm0503_puncture_mcs1_p1; +gsm0503_puncture_mcs1_p2; +gsm0503_puncture_mcs2_p1; +gsm0503_puncture_mcs2_p2; +gsm0503_puncture_mcs3_p1; +gsm0503_puncture_mcs3_p2; +gsm0503_puncture_mcs3_p3; +gsm0503_puncture_mcs4_p1; +gsm0503_puncture_mcs4_p2; +gsm0503_puncture_mcs4_p3; +gsm0503_puncture_mcs5_p1; +gsm0503_puncture_mcs5_p2; +gsm0503_puncture_mcs6_p1; +gsm0503_puncture_mcs6_p2; +gsm0503_puncture_mcs7_dl_hdr; +gsm0503_puncture_mcs7_ul_hdr; +gsm0503_puncture_mcs7_p1; +gsm0503_puncture_mcs7_p2; +gsm0503_puncture_mcs7_p3; +gsm0503_puncture_mcs8_p1; +gsm0503_puncture_mcs8_p2; +gsm0503_puncture_mcs8_p3; +gsm0503_puncture_mcs9_p1; +gsm0503_puncture_mcs9_p2; +gsm0503_puncture_mcs9_p3; +gsm0503_interleave_mcs5; +gsm0503_gsm_fr_map; +gsm0503_gsm_efr_protected_bits; +gsm0503_afs_ic_ubit; +gsm0503_afs_ic_sbit; +gsm0503_ahs_ic_ubit; +gsm0503_ahs_ic_sbit; +gsm0503_tch_hr_interleaving; +gsm0503_mcs5_usf_precode_table; + +gsm0503_xcch_deinterleave; +gsm0503_xcch_interleave; +gsm0503_tch_fr_deinterleave; +gsm0503_tch_fr_interleave; +gsm0503_tch_hr_deinterleave; +gsm0503_tch_hr_interleave; +gsm0503_mcs1_ul_interleave; +gsm0503_mcs1_ul_deinterleave; +gsm0503_mcs1_dl_interleave; +gsm0503_mcs1_dl_deinterleave; +gsm0503_mcs5_ul_interleave; +gsm0503_mcs5_ul_deinterleave; +gsm0503_mcs5_dl_interleave; +gsm0503_mcs5_dl_deinterleave; +gsm0503_mcs7_ul_interleave; +gsm0503_mcs7_ul_deinterleave; +gsm0503_mcs7_dl_interleave; +gsm0503_mcs7_dl_deinterleave; +gsm0503_mcs8_ul_interleave; +gsm0503_mcs8_ul_deinterleave; +gsm0503_mcs8_dl_interleave; +gsm0503_mcs8_dl_deinterleave; + +gsm0503_xcch_burst_unmap; +gsm0503_xcch_burst_map; +gsm0503_tch_burst_unmap; +gsm0503_tch_burst_map; +gsm0503_mcs5_ul_burst_map; +gsm0503_mcs5_ul_burst_unmap; +gsm0503_mcs7_ul_burst_map; +gsm0503_mcs7_ul_burst_unmap; +gsm0503_mcs5_dl_burst_map; +gsm0503_mcs5_dl_burst_unmap; +gsm0503_mcs7_dl_burst_map; +gsm0503_mcs7_dl_burst_unmap; +gsm0503_mcs5_burst_swap; + +gsm0503_fire_crc40; +gsm0503_cs234_crc16; +gsm0503_mcs_crc8_hdr; +gsm0503_mcs_crc12; +gsm0503_rach_crc6; +gsm0503_sch_crc10; +gsm0503_tch_fr_crc3; +gsm0503_tch_efr_crc8; +gsm0503_amr_crc6; + +gsm0503_egprs_mcs; +gsm0503_xcch_decode; +gsm0503_xcch_encode; +gsm0503_pdtch_decode; +gsm0503_pdtch_egprs_decode; +gsm0503_pdtch_encode; +gsm0503_pdtch_egprs_encode; +gsm0503_tch_fr_decode; +gsm0503_tch_fr_encode; +gsm0503_tch_hr_decode; +gsm0503_tch_hr_encode; +gsm0503_tch_afs_decode; +gsm0503_tch_afs_encode; +gsm0503_tch_ahs_decode; +gsm0503_tch_ahs_encode; +gsm0503_rach_decode; +gsm0503_rach_encode; +gsm0503_sch_decode; +gsm0503_sch_encode; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..7aa5a3c 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -1,7 +1,6 @@ #!/usr/bin/python2 -mod_license = """ -/* +mod_license = """/* * Copyright (C) 2011-2016 Sylvain Munaut * Copyright (C) 2016 sysmocom s.f.m.c. GmbH * @@ -27,7 +26,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, + name = "call-me", description = False, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +50,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -63,8 +68,13 @@ def _state_mask(self): return (1 << (self.k - 1)) - 1 + def combine(self, src, sel, nb): + x = src & sel + fn_xor = lambda x, y: x ^ y + return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) + def next_state(self, state, bit): - nb = combine( + nb = self.combine( (state << 1) | bit, self.poly_divider, self.k, @@ -85,9 +95,10 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -104,9 +115,9 @@ for p_n, p_d in self.polys: if self.recursive and p_d == 1: # Systematic output are replaced when in 'termination' mode - o = combine(src, self.poly_divider, self.k) + o = self.combine(src, self.poly_divider, self.k) else: - o = combine(src, p_n, self.k) + o = self.combine(src, p_n, self.k) rv.append(o) return rv @@ -121,61 +132,118 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" if len(self.puncture): - print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p - print >>fi, "};" + # Up to 12 numbers should be placed per line + counter = 0 - print >>fi, "\n/* %s */" % self.description - print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, \ + "\nstatic const int %s_puncture[] = {" % self.name + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n};\n") + + # Write description as a multiline comment + if self.description: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Write a final definition + print >>fi, \ + "const struct osmo_conv_code %s_%s = {" % (pref, self.name) + print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k print >>fi, "\t.len = %d," % self.block_len print >>fi, "\t.next_output = %s_output," % self.name print >>fi, "\t.next_state = %s_state," % self.name + if self.recursive: print >>fi, "\t.next_term_output = %s_term_output," % self.name print >>fi, "\t.next_term_state = %s_term_state," % self.name + if len(self.puncture): print >>fi, "\t.puncture = %s_puncture," % self.name + print >>fi, "};" poly = lambda *args: sum([(1 << x) for x in args]) - -def combine(src, sel, nb): - x = src & sel - fn_xor = lambda x, y: x ^ y - return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)]) # Polynomials according to 3GPP TS 05.03 Annex B G0 = poly(0, 3, 4) @@ -188,307 +256,487 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # RACH definition + ConvolutionalCode( + 14, + CCH_poly, + name = "rach", + description = ["RACH convolutional code"] + ), -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" -) + # SCH definition + ConvolutionalCode( + 35, + CCH_poly, + name = "sch", + description = ["SCH convolutional code"] + ), -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), + + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), + + # TCH_FR definition + ConvolutionalCode( + 185, + CCH_poly, + name = "tch_fr", + description = ["TCH/F convolutional code"] + ), + + # TCH_HR definition + ConvolutionalCode( + 98, + [ + ( G4, 1 ), + ( G5, 1 ), + ( G6, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, + 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, + 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214, + 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250, + 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295, + 298, 301, 304, 307, 310, -1, + ], + name = "tch_hr", + description = ["TCH/H convolutional code"] + ), + + # TCH_AHS_7_95 definition + ConvolutionalCode( + 129, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43, + 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95, + 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151, + 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191, + 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221, + 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251, + 255, 257, 259, 261, 263, 265, -1, + ], + name = "tch_ahs_7_95", + description = ["TCH/AHS 7.95 kbits convolutional code"] + ), + + # TCH_AHS_7_4 definition + ConvolutionalCode( + 126, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55, + 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119, + 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, + 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, + 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251, + 253, 255, 257, 259, -1, + ], + name = "tch_ahs_7_4", + description = ["TCH/AHS 7.4 kbits convolutional code"] + ), + + # TCH_AHS_6_7 definition + ConvolutionalCode( + 116, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, + 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189, + 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231, + 233, 235, 237, 239, -1, + ], + name = "tch_ahs_6_7", + description = ["TCH/AHS 6.7 kbits convolutional code"] + ), + + # TCH_AHS_5_9 definition + ConvolutionalCode( + 108, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211, + 215, 219, 221, 223, -1, + ], + name = "tch_ahs_5_9", + description = ["TCH/AHS 5.9 kbits convolutional code"] + ), + + # TCH_AHS_5_15 definition + ConvolutionalCode( + 97, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33, + 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93, + 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159, + 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, + 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, + 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261, + 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289, + 291, 294, 295, 297, 298, 300, 301, -1, + ], + name = "tch_ahs_5_15", + description = ["TCH/AHS 5.15 kbits convolutional code"] + ), + + # TCH_AHS_4_75 definition + ConvolutionalCode( + 89, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34, + 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, + 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166, + 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, + 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256, + 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283, + 284, -1, + ], + name = "tch_ahs_4_75", + description = ["TCH/AHS 4.75 kbits convolutional code"] + ), +] + +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 6 05:58:57 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 05:58:57 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: -Verified -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 05:59:05 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 05:59:05 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: -Verified -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 06:00:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 06:00:40 +0000 Subject: [ABANDON] osmo-pcu[master]: EGPRS: EPDAN decoding: add test case to show no ack_nack len... In-Reply-To: References: Message-ID: arvind.sirsikar has abandoned this change. Change subject: EGPRS: EPDAN decoding: add test case to show no ack_nack len issue ...................................................................... Abandoned same as https://gerrit.osmocom.org/#/c/804/ -- To view, visit https://gerrit.osmocom.org/765 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I8da84794748f2e81722c3eca69b46ccc3a21552e Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 6 06:00:51 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 06:00:51 +0000 Subject: [ABANDON] osmo-pcu[master]: Fix EGPRS EPDAN decoding: no ack nack dissector length In-Reply-To: References: Message-ID: arvind.sirsikar has abandoned this change. Change subject: Fix EGPRS EPDAN decoding: no ack nack dissector length ...................................................................... Abandoned same as https://gerrit.osmocom.org/#/c/804/ -- To view, visit https://gerrit.osmocom.org/766 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ieddf96aca82b0b0e917cfcc70aeb978799fb4e95 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 6 06:19:37 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Tue, 6 Sep 2016 06:19:37 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 22: > Patch Set 22: Code-Review+1 I have tried to address all the comments. please let me know the status. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 22 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 06:55:20 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 06:55:20 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#2). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M src/tbf.h M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 4 files changed, 83 insertions(+), 45 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/2 diff --git a/src/tbf.cpp b/src/tbf.cpp index 1fc1aef..6cd1e63 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -375,6 +375,9 @@ return -rc; } + if (this->is_egprs_enabled()) + this->calc_egprs_window_size(); + return 0; } @@ -780,20 +783,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->calc_egprs_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); @@ -1246,3 +1237,25 @@ { return ts == control_ts; } + +void gprs_rlcmac_tbf::calc_egprs_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(this->dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS DL window size to %d\n" + "base(%d) num_pdch(%d) ws_pdch(%d)\n", + this->name(), ws, bts_data->ws_base, num_pdch, + bts_data->ws_pdch); + + window()->set_ws(ws); +} diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..0013520 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -155,6 +155,7 @@ bool is_egprs_enabled() const; void enable_egprs(); void disable_egprs(); + void calc_egprs_window_size(); /* attempt to make things a bit more fair */ void rotate_in_list(); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..e74c676 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1814,17 +1814,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..ababd13 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -3365,7 +3365,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 3c -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 384 +base(128) num_pdch(4) ws_pdch(64) DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free @@ -3461,7 +3462,8 @@ - Setting Control TS 7 Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) Modifying MS object, TLLI: 0xf1223344 confirmed TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' @@ -3717,7 +3719,8 @@ - Setting Control TS 7 Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) Modifying MS object, TLLI: 0xf1223344 confirmed TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' @@ -3746,7 +3749,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4079,7 +4083,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4357,7 +4362,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4594,7 +4600,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4795,7 +4802,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4974,7 +4982,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5134,7 +5143,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5290,7 +5300,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5433,7 +5444,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5577,7 +5589,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5627,7 +5640,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5677,7 +5691,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5727,7 +5742,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5796,7 +5812,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5865,7 +5882,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5934,7 +5952,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6003,7 +6022,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6059,7 +6079,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6115,7 +6136,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6171,7 +6193,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6327,7 +6350,8 @@ - Setting Control TS 7 Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 64 +base(0) num_pdch(1) ws_pdch(0) Modifying MS object, TLLI: 0xf1223344 confirmed TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' @@ -6358,7 +6382,8 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 192 +base(128) num_pdch(1) ws_pdch(64) DL TBF slots: 0x10, N: 1, WS: 192 ********** TBF update ********** PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. @@ -6374,7 +6399,9 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS DL window size to 384 +base(128) num_pdch(4) ws_pdch(64) +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 6 07:14:25 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 07:14:25 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 2: Hi Neels and Holger, I have modified the patch as per your recommendation. Please review the same. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 11:47:09 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Tue, 6 Sep 2016 11:47:09 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 6: I have addressed all comments, Please let me know the status of the patch. -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 11:47:19 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Tue, 6 Sep 2016 11:47:19 +0000 Subject: osmo-pcu[master]: Update the function immediate assignment for EGPRS In-Reply-To: References: Message-ID: Patch Set 7: I have addressed all comments, Please let me know the status of the patch. -- To view, visit https://gerrit.osmocom.org/431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 11:58:04 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 11:58:04 +0000 Subject: [PATCH] osmo-bts[master]: oct: Attempt to enable the Octphy for the osmo-bts-oct build Message-ID: Review at https://gerrit.osmocom.org/817 oct: Attempt to enable the Octphy for the osmo-bts-oct build Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6 --- M contrib/jenkins_oct.sh 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/17/817/1 diff --git a/contrib/jenkins_oct.sh b/contrib/jenkins_oct.sh index 88b8c08..32b1407 100755 --- a/contrib/jenkins_oct.sh +++ b/contrib/jenkins_oct.sh @@ -47,7 +47,7 @@ # Build osmo-bts cd ../../ autoreconf --install --force -PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-openbsc=$PWD/deps/openbsc/openbsc/include --with-octsdr-2g=$PWD/deps/layer1-api/ +PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-openbsc=$PWD/deps/openbsc/openbsc/include --with-octsdr-2g=$PWD/deps/layer1-api/ --enable-octphy 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 -DISTCHECK_CONFIGURE_FLAGS="--with-octsdr-2g=$PWD/deps/layer1-api/ --with-openbsc=$PWD/deps/openbsc/openbsc/include" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck +DISTCHECK_CONFIGURE_FLAGS="--with-octsdr-2g=$PWD/deps/layer1-api/ --with-openbsc=$PWD/deps/openbsc/openbsc/include --enable-octphy" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/817 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Holger Freyther From gerrit-no-reply at lists.osmocom.org Tue Sep 6 12:00:11 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 12:00:11 +0000 Subject: osmo-bts[master]: oct: Attempt to enable the Octphy for the osmo-bts-oct build In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/817 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 12:00:15 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 12:00:15 +0000 Subject: [MERGED] osmo-bts[master]: oct: Attempt to enable the Octphy for the osmo-bts-oct build In-Reply-To: References: Message-ID: Holger Freyther has submitted this change and it was merged. Change subject: oct: Attempt to enable the Octphy for the osmo-bts-oct build ...................................................................... oct: Attempt to enable the Octphy for the osmo-bts-oct build Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6 --- M contrib/jenkins_oct.sh 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/contrib/jenkins_oct.sh b/contrib/jenkins_oct.sh index 88b8c08..32b1407 100755 --- a/contrib/jenkins_oct.sh +++ b/contrib/jenkins_oct.sh @@ -47,7 +47,7 @@ # Build osmo-bts cd ../../ autoreconf --install --force -PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-openbsc=$PWD/deps/openbsc/openbsc/include --with-octsdr-2g=$PWD/deps/layer1-api/ +PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-openbsc=$PWD/deps/openbsc/openbsc/include --with-octsdr-2g=$PWD/deps/layer1-api/ --enable-octphy 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 -DISTCHECK_CONFIGURE_FLAGS="--with-octsdr-2g=$PWD/deps/layer1-api/ --with-openbsc=$PWD/deps/openbsc/openbsc/include" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck +DISTCHECK_CONFIGURE_FLAGS="--with-octsdr-2g=$PWD/deps/layer1-api/ --with-openbsc=$PWD/deps/openbsc/openbsc/include --enable-octphy" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/817 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 6 12:53:34 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 12:53:34 +0000 Subject: [PATCH] osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... Message-ID: Review at https://gerrit.osmocom.org/818 DL TS allocation: add test case to show TS allocation for 2nd DL TBF This patch adds a test case test_2_consecutive_dl_tbfs which expects a current bug with TS allocation for 2nd DL TBF. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1792 Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 --- M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 2 files changed, 55 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/18/818/1 diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index b636b6e..0b4d1c1 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -792,6 +792,57 @@ test_many_connections(alloc_algorithm_dynamic, 160, "algorithm dynamic"); } +static void test_2_consecutive_dl_tbfs() +{ + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + gprs_rlcmac_tbf *dl_tbf1, *dl_tbf2; + uint8_t numTs1 = 0, numTs2 = 0; + + printf("Testing DL TS allocation for Multi UEs\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[4].enable(); + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf1); + + for (int i = 0; i < 8; i++) { + if (dl_tbf1->pdch[i]) + numTs1++; + } + OSMO_ASSERT(numTs1 == 4); + printf("TBF1: numTs(%d)\n", numTs1); + + dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf2); + + for (int i = 0; i < 8; i++) { + if (dl_tbf2->pdch[i]) + numTs2++; + } + + /* + * TODO: currently 2nd DL TBF gets 3 TS + * This behaviour will be fixed in subsequent patch + */ + printf("TBF2: numTs(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 != numTs1); + + tbf_free(dl_tbf1); + tbf_free(dl_tbf2); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -809,6 +860,7 @@ test_alloc_b(); test_successive_allocation(); test_many_connections(); + test_2_consecutive_dl_tbfs(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 9f88186..cbb65aa 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10793,3 +10793,6 @@ TBF[31] class 14 reserves ......C. TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs +Testing DL TS allocation for Multi UEs +TBF1: numTs(4) +TBF2: numTs(3) -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 6 12:53:34 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 6 Sep 2016 12:53:34 +0000 Subject: [PATCH] osmo-pcu[master]: Fix slot allocation based on direction configured Message-ID: Review at https://gerrit.osmocom.org/819 Fix slot allocation based on direction configured Earlier number of TS allocation for second DL TBF was less compared Compared to first TBF. As the allocation was considering combined capacity for TS allocation which was causing inconsistencies. This patch controls the TS allocation based on direction configured. Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.cpp M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 7 files changed, 69 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/1 diff --git a/src/bts.cpp b/src/bts.cpp index e65d608..ccbf691 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -622,6 +622,17 @@ bitvec_free(immediate_assignment); } +enum allocation_capacity BTS::get_ts_allocation_type() +{ + struct gprs_rlcmac_bts *bts = bts_data(); + + if (bts->capacity_type == 1) + return DL_ONLY; + else if (bts->capacity_type == 2) + return UL_ONLY; + else + return DL_UL_BOTH; +} GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class) { diff --git a/src/bts.h b/src/bts.h index 801342d..ae7c6c4 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,11 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum allocation_capacity { + DL_ONLY, + UL_ONLY, + DL_UL_BOTH +}; struct BTS; struct GprsMs; @@ -191,6 +196,13 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + /* + * 1 to support dl based allocation + * 2 for ul based allocation + * 3 for combined capacity:default + */ + uint8_t capacity_type; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; @@ -279,6 +291,9 @@ void set_current_block_frame_number(int frame_number, unsigned max_delay); int current_frame_number() const; + /* get TS allocation type */ + enum allocation_capacity get_ts_allocation_type(); + /** add paging to paging queue(s) */ int add_paging(uint8_t chan_needed, uint8_t *identity_lv); diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..fdba76e 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -509,6 +509,8 @@ enum {MASK_TT, MASK_TR}; unsigned mask_sel; + allocation_capacity capacity_type = bts->bts->get_ts_allocation_type(); + if (ms->ms_class() >= 32) { LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n", ms->ms_class()); @@ -775,8 +777,13 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) + if (capacity_type == UL_ONLY) { + if (tx_window < max_ul_slots) + continue; + } else if (capacity_type == DL_ONLY) { + if (rx_window < max_dl_slots) + continue; + } else if (capacity <= max_capacity) continue; max_capacity = capacity; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..273eab3 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->capacity_type = 3; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..289594d 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,25 @@ return CMD_SUCCESS; } +DEFUN(cfg_pcu_ts_allocation_capacity, + cfg_pcu_dl_ts_alloc_capacity_cmd, + "capacity-type (dl|ul)", + "TS allocation configuration based on capacity\n" + "enable DL capacity based allocation support\n" + "enable UL capacity based allocation support") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + if (!strcmp(argv[0], "dl")) + bts->capacity_type = 1; + else if (!strcmp(argv[0], "ul")) + bts->capacity_type = 2; + else + bts->capacity_type = 3; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +991,7 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_dl_ts_alloc_capacity_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 0b4d1c1..de6d0c7 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->capacity_type = 3; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->capacity_type = 3; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -660,6 +662,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->capacity_type = 3; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +701,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->capacity_type = 3; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +810,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->capacity_type = 1; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -821,7 +826,7 @@ numTs1++; } OSMO_ASSERT(numTs1 == 4); - printf("TBF1: numTs(%d)\n", numTs1); + printf("TBF1: numTs1(%d)\n", numTs1); dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); OSMO_ASSERT(dl_tbf2); @@ -831,13 +836,9 @@ numTs2++; } - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ - printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); - OSMO_ASSERT(numTs2 != numTs1); + printf("TBF2: numTs2(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 4); + OSMO_ASSERT(numTs2 == numTs1); tbf_free(dl_tbf1); tbf_free(dl_tbf2); @@ -861,6 +862,7 @@ test_successive_allocation(); test_many_connections(); test_2_consecutive_dl_tbfs(); + return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..abbd977 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10794,5 +10794,5 @@ TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs -TBF1: numTs(4) -TBF2: numTs(3) +TBF1: numTs1(4) +TBF2: numTs2(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:31:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 13:31:04 +0000 Subject: [PATCH] osmo-bts[master]: octphy: fix build: Revert "octphy: fix for multiple trx with... Message-ID: Review at https://gerrit.osmocom.org/820 octphy: fix build: Revert "octphy: fix for multiple trx with more than 1 dsp" This reverts commit 06968beab90806cba94c8b331276e4dc209c152b. Theoretically, this patch makes a lot of sense, but in order to be able to build osmo-bts-octphy until the headers version is clarified, revert use of usCentreArfcn: Above commit uses an usCentreArfcn member that is never defined in the history of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available. Also, the current headers version is apparently 02.07, though the octasic version numbers have been known to cause confusion among osmocom folks. This along with one other revert fixes this build problem: make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy' CC l1_oml.o l1_oml.c: In function ?l1if_trx_open?: l1_oml.c:1350:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; ^ l1_oml.c:1352:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = trx->arfcn; ^ In file included from ../../include/osmo-bts/logging.h:5:0, from l1_oml.c:33: l1_oml.c:1365:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, ^ Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e --- M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c 2 files changed, 2 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/20/820/1 diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index 82e73c8..ea0fb33 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -63,8 +63,7 @@ uint32_t rf_port_index; uint32_t rx_gain_db; uint32_t tx_atten_db; - /* arfcn used by TRX with id 0 */ - uint16_t center_arfcn; + struct octphy_hdl *hdl; } octphy; } u; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index c893b04..660fe1c 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1345,14 +1345,7 @@ oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; - - if (pinst->u.octphy.trx_id) - oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; - else { - oc->Config.usCentreArfcn = trx->arfcn; - plink->u.octphy.center_arfcn = trx->arfcn; - } - + oc->Config.usCentreArfcn = trx->bts->c0->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; -- To view, visit https://gerrit.osmocom.org/820 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:31:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 13:31:04 +0000 Subject: [PATCH] osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... Message-ID: Review at https://gerrit.osmocom.org/821 octphy: fix build: Revert "octphy: add support for multiple trx ids" This reverts commit c4fc00d8515ddc9990dfaf700c501cb8fe490cab. Theoretically, this patch makes a lot of sense, but in order to be able to build osmo-bts-octphy until the headers version is clarified, revert use of usCentreArfcn: Above commit uses an usCentreArfcn member that is never defined in the history of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available. Also, the current headers version is apparently 02.07, though the octasic version numbers have been known to cause confusion among osmocom folks. This along with one other revert fixes this build problem: make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy' CC l1_oml.o l1_oml.c: In function ?l1if_trx_open?: l1_oml.c:1350:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; ^ l1_oml.c:1352:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = trx->arfcn; ^ In file included from ../../include/osmo-bts/logging.h:5:0, from l1_oml.c:33: l1_oml.c:1365:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, ^ Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca --- M src/osmo-bts-octphy/l1_if.c M src/osmo-bts-octphy/l1_oml.c 2 files changed, 2 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/21/821/1 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index d621bcf..5a6716c 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -1555,7 +1555,6 @@ void bts_model_phy_instance_set_defaults(struct phy_instance *pinst) { - pinst->u.octphy.trx_id = pinst->num; } /*********************************************************************** diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 660fe1c..ed365b6 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1345,7 +1345,6 @@ oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; - oc->Config.usCentreArfcn = trx->bts->c0->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; @@ -1353,9 +1352,9 @@ oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " - "center=%u, tsc=%u, rx_gain=%u, tx_atten=%u)\n", + "tsc=%u, rx_gain=%u, tx_atten=%u)\n", oc->TrxId.byTrxId, oc->ulRfPortIndex, oc->Config.usArfcn, - oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, + oc->Config.usTsc, oc->RfConfig.ulRxGainDb, oc->RfConfig.ulTxAttndB); mOCTVC1_GSM_MSG_TRX_OPEN_CMD_SWAP(oc); -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:31:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 13:31:04 +0000 Subject: [PATCH] osmo-bts[master]: octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name ch... Message-ID: Review at https://gerrit.osmocom.org/822 octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name changed There was an apparent change of name from cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE to cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED in: git://git.osmocom.org/octphy-2g-headers commit 953a258aadf18c05e8128a339f15b1c5bb377cfd "Import headers from OCTSDR-OPENBSC-02.07.00-B708.tgz" In order to build octphy with these headers, apply the same rename in osmo-bts-octphy/*. Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3 --- M src/osmo-bts-octphy/l1_utils.c M src/osmo-bts-octphy/octphy_hw_api.c 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/22/822/1 diff --git a/src/osmo-bts-octphy/l1_utils.c b/src/osmo-bts-octphy/l1_utils.c index fd399a6..682865b 100644 --- a/src/osmo-bts-octphy/l1_utils.c +++ b/src/osmo-bts-octphy/l1_utils.c @@ -62,7 +62,7 @@ const struct value_string octphy_clkmgr_state_vals[8] = { { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNINITIALIZE, "UNINITIALIZED" }, - { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE, "IDLE" }, + { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED, "UNUSED" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_NO_EXT_CLOCK, "NO_EXT_CLOCK" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_LOCKED, "LOCKED" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNLOCKED, "UNLOCKED" }, diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index ec7c4be..d0d5ec7 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -279,7 +279,7 @@ static const struct value_string clocksync_state_vals[] = { { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNINITIALIZE, "Uninitialized" }, - { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE, "Idle" }, + { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED, "Unused" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_NO_EXT_CLOCK, "No External Clock" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_LOCKED, "Locked" }, -- To view, visit https://gerrit.osmocom.org/822 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:33:05 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 13:33:05 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: fix for multiple trx with... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/820 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:34:04 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 13:34:04 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/821/1/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 1558 You might want to keep this hunk? -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:36:31 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Tue, 6 Sep 2016 13:36:31 +0000 Subject: osmo-bts[master]: LC15: fix coding style In-Reply-To: References: Message-ID: Patch Set 1: This variable is unused. Please ignore it. -- To view, visit https://gerrit.osmocom.org/807 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18d07822df1f36a6855b72f83e2d73d221aa8735 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Minh-Quang Nguyen Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:37:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 13:37:15 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/821/1/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 1558 > You might want to keep this hunk? I also thought that, but assumed that it wasn't needed before. Looking now, it is however used elsewhere in the code. So that's why these things should be a separate commit to begin with :) -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:41:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 13:41:15 +0000 Subject: [PATCH] osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/821 to look at the new patch set (#2). octphy: fix build: Revert "octphy: add support for multiple trx ids" This reverts commit c4fc00d8515ddc9990dfaf700c501cb8fe490cab, except: we keep the part that sets the trx_id in bts_model_phy_instance_set_defaults(). Theoretically, this patch makes a lot of sense, but in order to be able to build osmo-bts-octphy until the headers version is clarified, revert use of usCentreArfcn: Above commit uses an usCentreArfcn member that is never defined in the history of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available. Also, the current headers version is apparently 02.07, though the octasic version numbers have been known to cause confusion among osmocom folks. This along with one other revert fixes this build problem: make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy' CC l1_oml.o l1_oml.c: In function ?l1if_trx_open?: l1_oml.c:1350:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; ^ l1_oml.c:1352:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = trx->arfcn; ^ In file included from ../../include/osmo-bts/logging.h:5:0, from l1_oml.c:33: l1_oml.c:1365:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, ^ Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 2 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/21/821/2 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 660fe1c..ed365b6 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1345,7 +1345,6 @@ oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; - oc->Config.usCentreArfcn = trx->bts->c0->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; @@ -1353,9 +1352,9 @@ oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " - "center=%u, tsc=%u, rx_gain=%u, tx_atten=%u)\n", + "tsc=%u, rx_gain=%u, tx_atten=%u)\n", oc->TrxId.byTrxId, oc->ulRfPortIndex, oc->Config.usArfcn, - oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, + oc->Config.usTsc, oc->RfConfig.ulRxGainDb, oc->RfConfig.ulTxAttndB); mOCTVC1_GSM_MSG_TRX_OPEN_CMD_SWAP(oc); -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:43:13 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Tue, 6 Sep 2016 13:43:13 +0000 Subject: osmo-bts[master]: LC15: Implementation of major BTS alarms In-Reply-To: References: Message-ID: Patch Set 1: >include/osmo-bts/oml.h >Line 50: >who defined those cause value? are they from TS 12.21? If yes, the >definitions should definitely go into libosmgsm abis_nm.h. If >the'yre custom definitions, we need to mention it clearly here, and >if possible also introduce a OSMO in the definition to make it >explicit those cause values are not standard cause values. Like >NM_EVT_CAUSE_OMSO_... Those custom alarms cause values are defined by NuranWireless. They will be named with OSMO to indicate non-standard cause values in next patches set. >src/common/bts.c >Line 180: >is the 'ceased alarm' mechanism really Litecell 1.5 specific, or is >it a more general feature that is shared among all BTS models? >src/common/rsl.c It is a general feature that is shared among other BTS models. >Line 397: >we typically don't indent the 'case' below a 'switch' >src/osmo-bts-litecell15/calib_file.c To be updated in next patches set >Line 156: >space missing, also in several other places. To be updated in next patches set -- To view, visit https://gerrit.osmocom.org/809 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic4e088a3af115d3d5a124b61c1e92eed277d3469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Minh-Quang Nguyen Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:44:55 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 13:44:55 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/821/1/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 1558 > I also thought that, but assumed that it wasn't needed before. Yes, and you remove the if/else in the next patch. -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 13:57:57 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Tue, 6 Sep 2016 13:57:57 +0000 Subject: libosmocore[master]: IPAC manufacture-defined measurement pre-processing definitions In-Reply-To: References: Message-ID: Patch Set 1: > (3 comments) Thanks for the suggestion. To be updated in next patch set. -- To view, visit https://gerrit.osmocom.org/812 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Minh-Quang Nguyen Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 14:30:57 2016 From: gerrit-no-reply at lists.osmocom.org (Minh-Quang Nguyen) Date: Tue, 6 Sep 2016 14:30:57 +0000 Subject: [PATCH] osmo-pcu[master]: LC15: Change TRX numbering for the latest Litecell15 hardware Message-ID: Review at https://gerrit.osmocom.org/823 LC15: Change TRX numbering for the latest Litecell15 hardware Change-Id: If3c4aff0366587dd3e5baa3d15b9e91d8ebe7753 --- M src/osmo-bts-litecell15/lc15_l1_if.c 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/23/823/1 diff --git a/src/osmo-bts-litecell15/lc15_l1_if.c b/src/osmo-bts-litecell15/lc15_l1_if.c index fe9dff1..a6358ba 100644 --- a/src/osmo-bts-litecell15/lc15_l1_if.c +++ b/src/osmo-bts-litecell15/lc15_l1_if.c @@ -364,8 +364,8 @@ fl1h->hLayer1 = hlayer1; fl1h->trx_no = trx_no; - /* hardware queues are numbered starting from 1 */ - fl1h->hw_info.trx_nr = trx_no + 1; + /* hardware queues are numbered starting from 0 */ + fl1h->hw_info.trx_nr = trx_no; DEBUGP(DL1IF, "PCU: Using TRX HW#%u\n", fl1h->hw_info.trx_nr); -- To view, visit https://gerrit.osmocom.org/823 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If3c4aff0366587dd3e5baa3d15b9e91d8ebe7753 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen From gerrit-no-reply at lists.osmocom.org Tue Sep 6 15:18:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 15:18:04 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/821/1/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 1558 > Yes, and you remove the if/else in the next patch. sorry, I don't follow. Do you mean the *previous* patch? The if/else removed there is entirely about that usCentreArfcn member. -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 16:03:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 16:03:01 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: (35 comments) I can't claim to understand in depth, so I have mainly style remarks. I'm not sure to what extent this is copying code over from another repos, in which case it might make sense to keep things similar rather than fix cosmetic issues. These remarks are just what catches my eye and strikes me as unusual for osmo* coding style. The commit log reads like this adds the generated code, yet in the patch it does look like the sources for generating are also included. It would be good to clarify that. (related: gsm6* files) https://gerrit.osmocom.org/#/c/816/4/.gitignore File .gitignore: Line 113: src/gsm/gsm6*.c gsm6? I thought this is about gsm05*? https://gerrit.osmocom.org/#/c/816/4//COMMIT_MSG Commit Message: Line 12: beeter to clean up the OsmoBTS source code, sharing this code. Better than what? Do you mean to say: "Having this code in libosmocore allows cleaning up the OsmoBTS source code." ? Line 28: in generated state. The general opinion about generated codes was to rather not even have them in git. Does this copy code from osmo-bts so that the sources to generate are in osmo-bts, but the generated code is in libosmocore? That would be rather unfortunate, IMHO the generating code should move along. https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503.h File include/osmocom/gsm/gsm0503.h: Line 29: /*! \file gsm0503.h This is an unrelated cosmetic fix, it should rather be in a separate commit. https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_coding.h File include/osmocom/gsm/gsm0503_coding.h: Line 1: /* (one space too many) Line 6: * (C) 2016 by Tom Tsou we usually have the copyright and license info only in the .c files... Line 46: int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); you're using stdint.h types, yet this header file has no #includes at all. It would be better to include definitions needed by this header explicitly. Where is ubit_t coming from? Line 78: int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, (extra space) https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_interleaving.h File include/osmocom/gsm/gsm0503_interleaving.h: Line 1: /* whitespace, copyright in .c Line 27: void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); missing #include(s) https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_mapping.h File include/osmocom/gsm/gsm0503_mapping.h: Line 1: /* whitespace, copyright in .c Line 27: void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, #include https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_parity.h File include/osmocom/gsm/gsm0503_parity.h: Line 1: /* ... https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_tables.h File include/osmocom/gsm/gsm0503_tables.h: Line 27: extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; #include https://gerrit.osmocom.org/#/c/816/4/src/gsm/Makefile.am File src/gsm/Makefile.am: Line 21: gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ Is the gsm610.c in src/codec related to these? Line 30: don't add a blank line here: don't separate libgsmint_*, and even if, don't add unrelated whitespace changes in the same commit. Line 42: $(AM_V_GEN)python2 ../../utils/conv_gen.py for 'make distcheck': rather use $(top_srcdir)/... ? (same below) https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_coding.c File src/gsm/gsm0503_coding.c: Line 1: /* whitespace https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_conv_edge.c File src/gsm/gsm0503_conv_edge.c: Line 62: one blank line too many -- but if the file is moving from somewhere else probably rather keep it... https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_interleaving.c File src/gsm/gsm0503_interleaving.c: Line 1: /* whitespace Line 304: (two blank lines, same as before) https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_mapping.c File src/gsm/gsm0503_mapping.c: Line 1: /* ws Line 29: sbit_t *hl, sbit_t *hn) this file mixes single-tab indent and aligned indent styles. would be better to stick to one of them. https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_parity.c File src/gsm/gsm0503_parity.c: Line 1: /* ws Line 33: would be nicer to not have a blank line between comment-for-struct and struct Line 145: drop trailing blank line https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_tables.c File src/gsm/gsm0503_tables.c: Line 1: /* ws https://gerrit.osmocom.org/#/c/816/4/utils/conv_gen.py File utils/conv_gen.py: Line 30: name = "call-me", description = False, puncture = []): IMHO pretty weird indenting choice. I'd have these fixes in a separate commit. lol: "LOL" :) Line 53: raise ValueError("Bad polynoms: " The proper English term would be polynomial / polynomials. I'd have these fixes in a separate commit. Line 59: "in a recursive code") separate commit. Line 98: # No choice ... (systematic output in recursive case) separate commit Line 135: def _print_term(self, fi, num_states, pack = False): fix whitespace in a separate commit Line 247: move combine() to self.combine() also in a separate commit Line 260: ( G1, 1 ), cosmetics in a separate comit (more below) Line 298: 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, I hope this is correct :) looks like pure magic, the numbers change weirdly. -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 16:53:13 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 16:53:13 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 6: (4 comments) almost... https://gerrit.osmocom.org/#/c/430/6/src/bts.cpp File src/bts.cpp: Line 515: if (is_11bit == 1) { another instance of 'if (is_11bit) {' Line 584: "phase access, but we force two phase access\n"); one missing indent Line 597: "received. MS requests single phase access " one missing indent Line 627: "phase access,but we force two phase access\n"); one missing indent -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:04:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:04:18 +0000 Subject: osmo-pcu[master]: Update the function immediate assignment for EGPRS In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 (5 comments) I still have some final polishing you could do, but I leave this at your discretion. These are no blockers. https://gerrit.osmocom.org/#/c/431/7/src/encoding.cpp File src/encoding.cpp: Line 206: } we would typically omit the curly braces when there is only one line of code in the if {} block. Line 252: if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || I would appreciate in-code comments here about where the ra bits go, like: ... Line 254: bitvec_write_field(dest, wp, 0x7f, 8); /* RACH value */ /* 11bit RA: the ra value is written below by write_ia_rest_egprs_uplink() */ Line 256: bitvec_write_field(dest, wp, ra, 8); /* RACH value */ /* 8bit RA: only the lower 8 bit of ra are used */ Line 257: } we would typically omit the curly braces when there is only one line of code in the if {} block. (though I'm not so sure how we do this when there are also comments) -- To view, visit https://gerrit.osmocom.org/431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:17:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:17:10 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 2: (3 comments) waiting for Holger to remove the -2... Some minor details remain. https://gerrit.osmocom.org/#/c/798/2/src/tbf.cpp File src/tbf.cpp: Line 380: Even nicer would be to do the cosmetic change of moving the calculation to a separate function in a separate commit, and adding this functional change in a second, small commit. I won't block on this though. Line 1244: unsigned int num_pdch = pcu_bitcount(this->dl_slots()); can 'this->' be omitted? Line 1256: "base(%d) num_pdch(%d) ws_pdch(%d)\n", you should not have multiple lines in a LOGP. Also, you should keep commits small: here, you move code and modify it at the same time. For patch readability, it is preferred to have only code modifications in the code-move that are absolutely necessary for the build (no cosmetic nor functional fixes). Do your tweaks and fixups in a separate commit. Since this is small, it's not a big problem here, but please try to stick to this principle. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:18:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:18:51 +0000 Subject: osmo-bts[master]: LC15: fix coding style In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) > This variable is unused. Please ignore it. If this 'i' is unused, then you should not add it in this commit. https://gerrit.osmocom.org/#/c/807/1/src/osmo-bts-litecell15/calib_file.c File src/osmo-bts-litecell15/calib_file.c: Line 151: st->fp = fopen(fname, "rb"); when you're fixing indenting, might as well fix the whole function block at the same time... -- To view, visit https://gerrit.osmocom.org/807 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18d07822df1f36a6855b72f83e2d73d221aa8735 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Minh-Quang Nguyen Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:22:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:22:02 +0000 Subject: osmo-pcu[master]: LC15: Change TRX numbering for the latest Litecell15 hardware In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/823 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If3c4aff0366587dd3e5baa3d15b9e91d8ebe7753 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:27:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:27:58 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: Theoretically this well reviewed by me, with Harald's and Arvind's +1, But let's still wait a bit whether Holger adds a +2... -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:34:08 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 17:34:08 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 1: octphy.trx_id is used at several places.. but we are reverting multi-trx support anyway and it will be initialized to 0 which hopefully is doing the right thing.. -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:34:44 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 17:34:44 +0000 Subject: osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:36:14 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 6 Sep 2016 17:36:14 +0000 Subject: osmo-bts[master]: octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name ch... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 Do we have any precedence of using #if for version checks? You can use #ifdef for both of them to support old and new headers? -- To view, visit https://gerrit.osmocom.org/822 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:38:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:38:11 +0000 Subject: [MERGED] osmo-bts[master]: octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name ch... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name changed ...................................................................... octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name changed There was an apparent change of name from cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE to cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED in: git://git.osmocom.org/octphy-2g-headers commit 953a258aadf18c05e8128a339f15b1c5bb377cfd "Import headers from OCTSDR-OPENBSC-02.07.00-B708.tgz" In order to build octphy with these headers, apply the same rename in osmo-bts-octphy/*. Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3 --- M src/osmo-bts-octphy/l1_utils.c M src/osmo-bts-octphy/octphy_hw_api.c 2 files changed, 2 insertions(+), 2 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/src/osmo-bts-octphy/l1_utils.c b/src/osmo-bts-octphy/l1_utils.c index fd399a6..682865b 100644 --- a/src/osmo-bts-octphy/l1_utils.c +++ b/src/osmo-bts-octphy/l1_utils.c @@ -62,7 +62,7 @@ const struct value_string octphy_clkmgr_state_vals[8] = { { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNINITIALIZE, "UNINITIALIZED" }, - { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE, "IDLE" }, + { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED, "UNUSED" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_NO_EXT_CLOCK, "NO_EXT_CLOCK" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_LOCKED, "LOCKED" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNLOCKED, "UNLOCKED" }, diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index ec7c4be..d0d5ec7 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -279,7 +279,7 @@ static const struct value_string clocksync_state_vals[] = { { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNINITIALIZE, "Uninitialized" }, - { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE, "Idle" }, + { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED, "Unused" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_NO_EXT_CLOCK, "No External Clock" }, { cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_LOCKED, "Locked" }, -- To view, visit https://gerrit.osmocom.org/822 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:38:12 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:38:12 +0000 Subject: [MERGED] osmo-bts[master]: octphy: fix build: Revert "octphy: add support for multiple ... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: octphy: fix build: Revert "octphy: add support for multiple trx ids" ...................................................................... octphy: fix build: Revert "octphy: add support for multiple trx ids" This reverts commit c4fc00d8515ddc9990dfaf700c501cb8fe490cab, except: we keep the part that sets the trx_id in bts_model_phy_instance_set_defaults(). Theoretically, this patch makes a lot of sense, but in order to be able to build osmo-bts-octphy until the headers version is clarified, revert use of usCentreArfcn: Above commit uses an usCentreArfcn member that is never defined in the history of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available. Also, the current headers version is apparently 02.07, though the octasic version numbers have been known to cause confusion among osmocom folks. This along with one other revert fixes this build problem: make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy' CC l1_oml.o l1_oml.c: In function ?l1if_trx_open?: l1_oml.c:1350:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; ^ l1_oml.c:1352:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = trx->arfcn; ^ In file included from ../../include/osmo-bts/logging.h:5:0, from l1_oml.c:33: l1_oml.c:1365:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, ^ Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 2 insertions(+), 3 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 660fe1c..ed365b6 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1345,7 +1345,6 @@ oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; - oc->Config.usCentreArfcn = trx->bts->c0->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; @@ -1353,9 +1352,9 @@ oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " - "center=%u, tsc=%u, rx_gain=%u, tx_atten=%u)\n", + "tsc=%u, rx_gain=%u, tx_atten=%u)\n", oc->TrxId.byTrxId, oc->ulRfPortIndex, oc->Config.usArfcn, - oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, + oc->Config.usTsc, oc->RfConfig.ulRxGainDb, oc->RfConfig.ulTxAttndB); mOCTVC1_GSM_MSG_TRX_OPEN_CMD_SWAP(oc); -- To view, visit https://gerrit.osmocom.org/821 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:38:12 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:38:12 +0000 Subject: [MERGED] osmo-bts[master]: octphy: fix build: Revert "octphy: fix for multiple trx with... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: octphy: fix build: Revert "octphy: fix for multiple trx with more than 1 dsp" ...................................................................... octphy: fix build: Revert "octphy: fix for multiple trx with more than 1 dsp" This reverts commit 06968beab90806cba94c8b331276e4dc209c152b. Theoretically, this patch makes a lot of sense, but in order to be able to build osmo-bts-octphy until the headers version is clarified, revert use of usCentreArfcn: Above commit uses an usCentreArfcn member that is never defined in the history of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available. Also, the current headers version is apparently 02.07, though the octasic version numbers have been known to cause confusion among osmocom folks. This along with one other revert fixes this build problem: make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy' CC l1_oml.o l1_oml.c: In function ?l1if_trx_open?: l1_oml.c:1350:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; ^ l1_oml.c:1352:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn = trx->arfcn; ^ In file included from ../../include/osmo-bts/logging.h:5:0, from l1_oml.c:33: l1_oml.c:1365:13: error: ?tOCTVC1_GSM_TRX_CONFIG? has no member named ?usCentreArfcn? oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb, ^ Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e --- M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c 2 files changed, 2 insertions(+), 10 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index 82e73c8..ea0fb33 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -63,8 +63,7 @@ uint32_t rf_port_index; uint32_t rx_gain_db; uint32_t tx_atten_db; - /* arfcn used by TRX with id 0 */ - uint16_t center_arfcn; + struct octphy_hdl *hdl; } octphy; } u; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index c893b04..660fe1c 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1345,14 +1345,7 @@ oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; - - if (pinst->u.octphy.trx_id) - oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn; - else { - oc->Config.usCentreArfcn = trx->arfcn; - plink->u.octphy.center_arfcn = trx->arfcn; - } - + oc->Config.usCentreArfcn = trx->bts->c0->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; -- To view, visit https://gerrit.osmocom.org/820 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:40:25 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:40:25 +0000 Subject: openbsc[master]: cosmetic: transaction.h: 1 comment typo, 1 whitespace In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 not wasting any time on these cosmetics... -- To view, visit https://gerrit.osmocom.org/791 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia2629f9d9887b50b25c6996531b7ef518fb33335 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 6 17:43:46 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 6 Sep 2016 17:43:46 +0000 Subject: openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Patch Set 4: (1 comment) https://gerrit.osmocom.org/#/c/551/4/openbsc/include/openbsc/gsm_data.h File openbsc/include/openbsc/gsm_data.h: Line 220: [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "While trying to deliver an unknown error attempted."}, attempted? should be 'occured', right? Nitpicking: the other messages use this order of words: 'Unknown error during sms delivery attempt' (though I'd have some fixed for those, too) -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 18:00:58 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Tue, 6 Sep 2016 18:00:58 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: (15 comments) https://gerrit.osmocom.org/#/c/816/4//COMMIT_MSG Commit Message: Line 12: beeter to clean up the OsmoBTS source code, sharing this code. > Better than what? Yes, thanks. I'll change it. Line 28: in generated state. > The general opinion about generated codes was to rather not In OsmoBTS there are already generated convolutional codes. So, I spent some time finding corresponding polynomial sets for some data types, which wasn't defined in the conv_gen.py generator. Despite the EDGE's MCS levels use the same generator polynomial with different lengths, I wasn't able to find any details about EDGE convolutional transcoding, so I merely copied those tables from OsmoBTS into a separate file. I still have some doubts, related to MCS codes... They aren't covered by GSM 05.03, so should I migrate them in separate commit? Should I use a separate file? Which name to use for this file? https://gerrit.osmocom.org/#/c/816/4/include/osmocom/gsm/gsm0503_coding.h File include/osmocom/gsm/gsm0503_coding.h: Line 6: * (C) 2016 by Tom Tsou > we usually have the copyright and license info only in the .c files... I just followed the gsm0503.h as an example, because there was such information... But I am agree with you. Line 46: int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); > you're using stdint.h types, yet this header file has no #includes at all. Ok, I need to add the following: #include #include https://gerrit.osmocom.org/#/c/816/4/src/gsm/Makefile.am File src/gsm/Makefile.am: Line 21: gsm610.c gsm620.c gsm660.c gsm0503_conv.c \ > Is the gsm610.c in src/codec related to these? This is because the gsm0503_coding.c has some dependences from libosmocodec. Maybe there is a better way to link these dependences? Line 30: > don't add a blank line here: Ok, I will fix it. Line 42: $(AM_V_GEN)python2 ../../utils/conv_gen.py > for 'make distcheck': rather use $(top_srcdir)/... ? Ok, it would be better. https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_conv_edge.c File src/gsm/gsm0503_conv_edge.c: Line 62: > one blank line too many -- but if the file is moving from Yes, it is a code part from OsmoBTS, and there was even more blank lines, twice after every 'const struct osmo_conv_code...' definition. :) I used this separation (two blank lines) to separate tables from definitions and to increase readability... https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_interleaving.c File src/gsm/gsm0503_interleaving.c: Line 304: > (two blank lines, same as before) Just copied 'as is', but I can fix it. https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_mapping.c File src/gsm/gsm0503_mapping.c: Line 29: sbit_t *hl, sbit_t *hn) > this file mixes single-tab indent and aligned indent styles. Ok, will be fixed. https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_parity.c File src/gsm/gsm0503_parity.c: Line 33: > would be nicer to not have a blank line between comment-for-struct and stru It also was taken 'as is', will be fixed. https://gerrit.osmocom.org/#/c/816/4/utils/conv_gen.py File utils/conv_gen.py: Line 30: name = "call-me", description = False, puncture = []): > IMHO pretty weird indenting choice. How to separate this big line better? I have some doubts... How many tabs should I use? Line 53: raise ValueError("Bad polynoms: " > The proper English term would be polynomial / polynomials. I am not an author of this code, but I will fix it. Line 59: "in a recursive code") > separate commit. Ok, I was thinking about that... Line 298: 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, > I hope this is correct :) For me this is magic too, and this is why I merely copied the puncture tables 'as is'. Just decreased tabs count... -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 6 22:08:06 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Tue, 6 Sep 2016 22:08:06 +0000 Subject: [PATCH] openbsc[master]: Build fixes and cleanups Message-ID: Review at https://gerrit.osmocom.org/824 Build fixes and cleanups Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I9bd4f7a0b0bce0184f093ac61099c6681a458f65 --- M openbsc/src/gprs/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 6 files changed, 41 insertions(+), 23 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/24/824/1 diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..280a029 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -8,7 +8,7 @@ endif OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) + $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) $(LIBOSMOABIS_LIBS) $(LIBGTP_LIBS) bin_PROGRAMS = osmo-gbproxy @@ -31,20 +31,17 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +osmo_sgsn_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) $(LIBCARES_LIBS) $(LIBCRYPTO_LIBS) -lrt + if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) endif 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 + +osmo_gtphub_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ + $(LIBGTP_LIBS) $(LIBCARES_LIBS) -lrt diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..9a6810e 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,8 +1,15 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS = -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(COVERAGE_CFLAGS) noinst_LIBRARIES = libiu.a diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..8dfc56c 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,5 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CFLAGS=-Wall -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBGTP_CFLAGS) EXTRA_DIST = \ gtphub_test.ok @@ -20,5 +23,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt + $(LIBGTP_LIBS) \ + -lrt diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..5cac3f8 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -2,7 +2,8 @@ AM_CFLAGS=-Wall \ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) + $(LIBCRYPTO_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) noinst_PROGRAMS = mm_auth_test diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..0e73d04 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,5 +1,11 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CFLAGS = \ + -Wall -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) + if BUILD_IU AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) endif @@ -41,7 +47,9 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + $(LIBGTP_LIBS) \ + -lrt + if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..08eae47 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -16,6 +16,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm + $(LIBGTP_LIBS) \ + -lrt -lm -- To view, visit https://gerrit.osmocom.org/824 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9bd4f7a0b0bce0184f093ac61099c6681a458f65 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer From gerrit-no-reply at lists.osmocom.org Wed Sep 7 10:22:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 7 Sep 2016 10:22:33 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: (1 comment) > In OsmoBTS there are already generated convolutional codes. > So, I spent some time finding corresponding polynomial sets for > some data types, which wasn't defined in the conv_gen.py generator. Sounds like excellent work! Did you find them mathematically, or in specs out there? :) > Despite the EDGE's MCS levels use the same generator polynomial > with different lengths, I wasn't able to find any details about > EDGE convolutional transcoding, so I merely copied those tables > from OsmoBTS into a separate file. Ah, so there's two parts here. The commit log sounded at first like there was one set of codes. Sounds like it makes sense to split in two commits to make things perfectly clear. > I still have some doubts, related to MCS codes... > They aren't covered by GSM 05.03, so should I migrate them > in separate commit? Should I use a separate file? Which name to > use for this file? Yes and yes -- feel free to invent a new file name. A GSM spec number would be best to match the other file names -- but you say the EDGE codes are not covered by a specific GSM spec? As a fallback I'd suggest something like 'gsm_edge_coding.c' or 'gsm_mcs_coding.c'? I assume you have a better understanding of what name would be proper. BTW, osmo-nitb's main C file is still called 'bsc_hack.c' :) (Though libosmocore would be a place where we're stricter about naming.) https://gerrit.osmocom.org/#/c/816/4/src/gsm/gsm0503_conv_edge.c File src/gsm/gsm0503_conv_edge.c: Line 62: > Yes, it is a code part from OsmoBTS, and there was even more blank lines, t I think it would be best to first copy the code from OsmoBTS exactly as-is, preferably so that a diff between the files (or code chunks) ends up completely empty. Then add any cosmetic changes in a subsequent commit. (Same for all other cosmetics we've commented on.) -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 7 10:56:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 7 Sep 2016 10:56:11 +0000 Subject: openbsc[master]: Build fixes and cleanups In-Reply-To: References: Message-ID: Patch Set 1: (8 comments) https://gerrit.osmocom.org/#/c/824/1/openbsc/src/gprs/Makefile.am File openbsc/src/gprs/Makefile.am: Line 35: $(OSMO_LIBS) $(LIBCARES_LIBS) $(LIBCRYPTO_LIBS) -lrt Here and below, it is rather complex to see what is a fix and what is cosmetic. Please put the cosmetic cleanups in a separate commit. https://gerrit.osmocom.org/#/c/824/1/openbsc/src/libiu/Makefile.am File openbsc/src/libiu/Makefile.am: Line 12: $(COVERAGE_CFLAGS) Again, rather don't mix cosmetics with functional changes https://gerrit.osmocom.org/#/c/824/1/openbsc/tests/gtphub/Makefile.am File openbsc/tests/gtphub/Makefile.am: Line 2: AM_CFLAGS=-Wall -ggdb3 \ (the commit with cosmetic fixes could add spaces around the '=' here) https://gerrit.osmocom.org/#/c/824/1/openbsc/tests/mm_auth/Makefile.am File openbsc/tests/mm_auth/Makefile.am: Line 2: AM_CFLAGS=-Wall \ (' = ') https://gerrit.osmocom.org/#/c/824/1/openbsc/tests/sgsn/Makefile.am File openbsc/tests/sgsn/Makefile.am: Line 6: $(LIBCARES_CFLAGS) \ (separate commit) Line 8: since 'if BUILD_IU' adds more items to AM_CFLAGS, I guess we should not add a blank line here Line 42: $(top_builddir)/src/gprs/gprs_llc_xid.o \ another pre-existing whitespace error :) (should be tab to indent) Line 52: again, still related to sgsn_test_*, so I'd not add a blank line -- To view, visit https://gerrit.osmocom.org/824 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9bd4f7a0b0bce0184f093ac61099c6681a458f65 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 7 11:48:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 7 Sep 2016 11:48:37 +0000 Subject: [MERGED] osmo-pcu[master]: LC15: Change TRX numbering for the latest Litecell15 hardware In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: LC15: Change TRX numbering for the latest Litecell15 hardware ...................................................................... LC15: Change TRX numbering for the latest Litecell15 hardware Change-Id: If3c4aff0366587dd3e5baa3d15b9e91d8ebe7753 --- M src/osmo-bts-litecell15/lc15_l1_if.c 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/lc15_l1_if.c b/src/osmo-bts-litecell15/lc15_l1_if.c index fe9dff1..a6358ba 100644 --- a/src/osmo-bts-litecell15/lc15_l1_if.c +++ b/src/osmo-bts-litecell15/lc15_l1_if.c @@ -364,8 +364,8 @@ fl1h->hLayer1 = hlayer1; fl1h->trx_no = trx_no; - /* hardware queues are numbered starting from 1 */ - fl1h->hw_info.trx_nr = trx_no + 1; + /* hardware queues are numbered starting from 0 */ + fl1h->hw_info.trx_nr = trx_no; DEBUGP(DL1IF, "PCU: Using TRX HW#%u\n", fl1h->hw_info.trx_nr); -- To view, visit https://gerrit.osmocom.org/823 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If3c4aff0366587dd3e5baa3d15b9e91d8ebe7753 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 7 12:57:57 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 7 Sep 2016 12:57:57 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding Message-ID: Review at https://gerrit.osmocom.org/825 EGPRS: add test case to show LI decoding This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 288 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/1 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..06153b9 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate row 4 of Table 10.4.14a.1 + * should expect 1 complete. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* TODO: we should see 2 chunks here */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + /* + * TODO: it should be complete + * and length as 0 + */ + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..b00c49e 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -619,6 +619,124 @@ &ulreq, tbf->poll_fn); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts, uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) @@ -1868,6 +1986,41 @@ printf("=== end %s ===\n", __func__); } +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 7 12:57:58 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 7 Sep 2016 12:57:58 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 Message-ID: Review at https://gerrit.osmocom.org/826 EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 Earlier there was no proper handling row 4 of Table 10.4.14a.1 of 44.060. Which has been fixed in this patch. Related: OS#1811 Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b --- M src/decoding.cpp M src/tbf_ul.cpp M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 5 files changed, 26 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/26/826/1 diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..515a75c 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -73,8 +73,8 @@ chunks[num_chunks].is_complete = true; } else if (li->li == 0 && num_chunks == 0 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 4 */ - chunks[num_chunks].length = LENGTH_TO_END; - chunks[num_chunks].is_complete = is_last_block; + chunks[num_chunks].length = 0; + chunks[num_chunks].is_complete = true; } else if (li->li == 127 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 3 & 5 */ /* only filling bytes left */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 7e0732c..f67ffd7 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -67,14 +67,18 @@ for (i = 0; i < num_frames; i++) { frame = frames + i; - bts->rlc_ul_payload_bytes(frame->length); + if (frame->length) { + bts->rlc_ul_payload_bytes(frame->length); - LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d starts at offset %d, " - "length=%d, is_complete=%d\n", - i + 1, frame->offset, frame->length, frame->is_complete); + LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d " + "starts at offset %d, " + "length=%d, is_complete=%d\n", + i + 1, frame->offset, frame->length, + frame->is_complete); - m_llc.append_frame(data + frame->offset, frame->length); - m_llc.consume(frame->length); + m_llc.append_frame(data + frame->offset, frame->length); + m_llc.consume(frame->length); + } if (frame->is_complete) { /* send frame to SGSN */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 06153b9..3537aa7 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,31 +496,24 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); - /* - * TODO: simulate row 4 of Table 10.4.14a.1 - * should expect 1 complete. but currently it fails - * due to bug. The assert will be fixed along with actual - * fix - */ rdbi.e = 0; rdbi.ti = 0; - rdbi.cv = 0; + rdbi.cv = 1; tlli = 0; offs = 0; data[offs++] = 1; num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, chunks, ARRAY_SIZE(chunks), &tlli); - /* TODO: we should see 2 chunks here */ - OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(num_chunks == 2); OSMO_ASSERT(chunks[0].offset == 1); - /* - * TODO: it should be complete - * and length as 0 - */ - OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].length == 0); OSMO_ASSERT(chunks[0].is_complete); + OSMO_ASSERT(chunks[1].offset == 1); + OSMO_ASSERT(chunks[1].length == 43); + OSMO_ASSERT(!chunks[1].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index b00c49e..81a41bf 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -727,12 +727,13 @@ egprs3->rsb = 0; egprs3->spb = 0; egprs3->pi = 0; + + /* row 4 of Table 10.4.14a.1 */ data_msg[4] = 0x2; data_msg[5] = 0x0; pdch->rcv_block(data_msg, 49, *fn, &meas); - /* TODO: should expect m_index as 43 */ - OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + OSMO_ASSERT(ul_tbf->m_llc.m_index == 43); return ul_tbf; } diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index aceb9b4..18ca207 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6463,7 +6463,10 @@ - Raising V(R) to 2 - Taking block 1 out, raising V(Q) to 2 - Assembling frames: (len=44) --- Frame 1 starts at offset 1, length=43, is_complete=0 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) complete UL frame len=44 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) len=44 +No bctx +-- Frame 2 starts at offset 1, length=43, is_complete=0 - No gaps in received block, last block: BSN=1 CV=7 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 7 13:07:32 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 13:07:32 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: First of all, thank you for detailed review! > > In OsmoBTS there are already generated convolutional codes. > > So, I spent some time finding corresponding polynomial sets for > > some data types, which wasn't defined in the conv_gen.py > generator. > > Sounds like excellent work! Did you find them mathematically, or in > specs out there? :) This might actually sound strange, but I am still have not clear understanding, how does the polynomial generator work in details. Some polynomial sets I have been able to find exactly in the GSM 05.03 specification, some others (mostly TCH/AHS*) aren't covered there. After several unsuccessful attempts to find something useful in Google, I found, that some TCH/AHS codes match with the TCH/AFS codes with different length and punctures. > > Despite the EDGE's MCS levels use the same generator polynomial > > with different lengths, I wasn't able to find any details about > > EDGE convolutional transcoding, so I merely copied those tables > > from OsmoBTS into a separate file. > > Ah, so there's two parts here. The commit log sounded at first like > there was one set of codes. Sounds like it makes sense to split > in two commits to make things perfectly clear. Yeah, I really need to separate this commit... Maybe this way? - utils/conv_gen.py: code style changes (line width, tabs, etc.) - utils/conv_gen.py: improve output formatting (4 blocks / 12 numbers per line) - utils/conv_gen.py: generate a single file - gsm/gsm0503: migrate transcoding routines from OsmoBTS (without EDGE for now) - ??? EDGE specification ???: add EDGE/MCS transcoding routines As Sylvain said, the MCS convolutional codes may be generated using the conv_gen.py. So, as soon as I find corresponding polynomials, I'll do it. > > I still have some doubts, related to MCS codes... > > They aren't covered by GSM 05.03, so should I migrate them > > in separate commit? Should I use a separate file? Which name to > > use for this file? > > Yes and yes -- feel free to invent a new file name. A GSM spec > number would be best to match the other file names -- but you say > the EDGE codes are not covered by a specific GSM spec? As a > fallback I'd suggest something like 'gsm_edge_coding.c' or > 'gsm_mcs_coding.c'? I assume you have a better understanding of > what name would be proper. They aren't covered by GSM 05.03 :( Tom Tsou probably knows the answer, but he is a bit busy right now. -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 7 14:38:41 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Wed, 7 Sep 2016 14:38:41 +0000 Subject: [PATCH] osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Hello Harald Welte, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/430 to look at the new patch set (#7). Handle EGPRS 11 bit RACH in osmo-pcu A function is_single_block is added to get request type of RACH. EGPRS 11 bit RACH is handled. Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 --- M src/bts.cpp M src/bts.h 2 files changed, 81 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/30/430/7 diff --git a/src/bts.cpp b/src/bts.cpp index e65d608..a726545 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -479,20 +479,16 @@ uint8_t usf = 7; uint8_t tsc; uint16_t ta; + uint16_t ms_class = 0; + uint16_t priority = 0; rach_frame(); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + if (qta < 0) qta = 0; if (qta > 252) @@ -515,8 +511,16 @@ } else { // Create new TBF #warning "Copy and paste with other routines.." - /* set class to 0, since we don't know the multislot class yet */ - tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + + if (is_11bit) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0,as we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); /* FIXME: send reject */ @@ -564,6 +568,70 @@ return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (!val) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase access " + "but we force two phase access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access,but we force two phase access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index 801342d..ba6fc4d 100644 --- a/src/bts.h +++ b/src/bts.h @@ -290,6 +290,8 @@ int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst_type); -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Wed Sep 7 15:36:35 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 15:36:35 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: code style changes (line width, tabs, etc.) Message-ID: Review at https://gerrit.osmocom.org/827 utils/conv_gen.py: code style changes (line width, tabs, etc.) Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 --- M utils/conv_gen.py 1 file changed, 233 insertions(+), 181 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/27/827/1 diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..a4f918f 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -27,7 +27,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, name, + description = None, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +51,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -85,7 +91,8 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: o = combine(src, p_n, self.k) rv.append(o) @@ -121,32 +128,48 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): d = [] for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + d.append("%d, " % x) print >>fi, "\t%s" % ''.join(d) def _print_x(self, fi, num_states, pack = False): for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + print >>fi, "\t{ %2d, %2d }," % (x0, x1) def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" @@ -156,7 +179,14 @@ print >>fi, "\t%d," % p print >>fi, "};" - print >>fi, "\n/* %s */" % self.description + # Write description as a multi-line comment + if self.description is not None: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Print a final convolutional code definition print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k @@ -188,93 +218,102 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] +# xCCH definition xCCH = ConvolutionalCode( 224, CCH_poly, name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# CS2 definition CS2 = ConvolutionalCode( 290, CCH_poly, puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# CS3 definition CS3 = ConvolutionalCode( 334, CCH_poly, puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# TCH_AFS_12_2 definition TCH_AFS_12_2 = ConvolutionalCode( 250, [ ( 1, 1 ), ( G1, G0 ), ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] ) +# TCH_AFS_10_2 definition TCH_AFS_10_2 = ConvolutionalCode( 210, [ @@ -283,32 +322,34 @@ ( 1, 1 ), ], puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] ) +# TCH_AFS_7_95 definition TCH_AFS_7_95 = ConvolutionalCode( 165, [ @@ -317,21 +358,23 @@ ( G6, G4 ), ], puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] ) +# TCH_AFS_7_4 definition TCH_AFS_7_4 = ConvolutionalCode( 154, [ @@ -340,18 +383,20 @@ ( 1, 1 ), ], puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] ) +# TCH_AFS_6_7 definition TCH_AFS_6_7 = ConvolutionalCode( 140, [ @@ -361,27 +406,29 @@ ( 1, 1 ), ], puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] ) +# TCH_AFS_5_9 definition TCH_AFS_5_9 = ConvolutionalCode( 124, [ @@ -391,24 +438,26 @@ ( 1, 1), ], puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] ) +# TCH_AFS_5_15 definition TCH_AFS_5_15 = ConvolutionalCode( 109, [ @@ -419,27 +468,29 @@ ( 1, 1 ), ], puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] ) +# TCH_AFS_4_75 definition TCH_AFS_4_75 = ConvolutionalCode( 101, [ @@ -450,23 +501,24 @@ ( 1, 1 ), ], puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] ) def gen_c(dest, pref, code): -- To view, visit https://gerrit.osmocom.org/827 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Wed Sep 7 15:36:35 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 15:36:35 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: generate a single file Message-ID: Review at https://gerrit.osmocom.org/828 utils/conv_gen.py: generate a single file Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa --- M .gitignore M src/gsm/Makefile.am M utils/conv_gen.py 3 files changed, 309 insertions(+), 316 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/828/1 diff --git a/.gitignore b/.gitignore index 5165364..90c8c85 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,7 @@ doc/*.tag src/crc*gen.c -src/gsm/conv*gen.c +src/gsm/gsm0503_conv.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..9a9d96f 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,11 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c + gsup.c gprs_gea.c gsm0503_conv.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +32,6 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py - $(AM_V_GEN)python2 ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: + $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py diff --git a/utils/conv_gen.py b/utils/conv_gen.py index a4f918f..38ea63b 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -222,325 +222,322 @@ ( G1, 1 ), ] -# xCCH definition -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description = [ - "xCCH convolutional code:", - "228 bits blocks, rate 1/2, k = 5", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS2 definition -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description = [ - "CS2 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS3 definition -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description = [ - "CS3 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# TCH_AFS_12_2 definition -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = [ - "TCH/AFS 12.2 kbits convolutional code:", - "250 bits block, rate 1/2, punctured", - "G0/G0 = 1", - "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", - ] -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -# TCH_AFS_10_2 definition -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = [ - "TCH/AFS 10.2 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_7_95 definition -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = [ - "TCH/AFS 7.95 kbits convolutional code:", - "G4/G4 = 1", - "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", - "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", - ] -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -# TCH_AFS_7_4 definition -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = [ - "TCH/AFS 7.4 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_6_7 definition -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = [ - "TCH/AFS 6.7 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_5_9 definition -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = [ - "TCH/AFS 5.9 kbits convolutional code:", - "124 bits", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -# TCH_AFS_5_15 definition -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = [ - "TCH/AFS 5.15 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_4_75 definition -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = [ - "TCH/AFS 4.75 kbits convolutional code:", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ) +] -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Wed Sep 7 15:36:36 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 15:36:36 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: improve output formatting Message-ID: Review at https://gerrit.osmocom.org/829 utils/conv_gen.py: improve output formatting Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c --- M src/gsm/Makefile.am M utils/conv_gen.py 2 files changed, 43 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/29/829/1 diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 9a9d96f..d367c89 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -35,3 +35,5 @@ # Convolutional codes generation gsm0503_conv.c: $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py + +CLEANFILES = gsm0503_conv.c diff --git a/utils/conv_gen.py b/utils/conv_gen.py index 38ea63b..5a519bc 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -129,17 +129,30 @@ return ns, nb def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): if pack: x = pack(self.next_term_output(state)) else: x = self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): if pack: x0 = pack(self.next_output(state, 0)) @@ -148,7 +161,30 @@ x0 = self.next_state(state, 0) x1 = self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") + + def _print_puncture(self, fi): + # Up to 12 numbers should be placed per line + counter = 0 + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): pack = lambda n: \ @@ -173,10 +209,10 @@ self._print_term(fi, num_states, pack) print >>fi, "};" + # Write puncture if preset if len(self.puncture): print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p + self._print_puncture(fi) print >>fi, "};" # Write description as a multi-line comment -- To view, visit https://gerrit.osmocom.org/829 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Wed Sep 7 15:38:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 7 Sep 2016 15:38:49 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: > First of all, thank you for detailed review! It's a pleasure :) > Yeah, I really need to separate this commit... Maybe this way? > > - utils/conv_gen.py: code style changes (line width, tabs, etc.) > - utils/conv_gen.py: improve output formatting (4 blocks / 12 > numbers per line) > - utils/conv_gen.py: generate a single file > > - gsm/gsm0503: migrate transcoding routines from OsmoBTS (without > EDGE for now) > - ??? EDGE specification ???: add EDGE/MCS transcoding routines Splitting the commits this way looks excellent to me. -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 7 16:11:42 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 16:11:42 +0000 Subject: [PATCH] libosmocore[master]: gsm/gsm0503.h: fix typo Message-ID: Review at https://gerrit.osmocom.org/830 gsm/gsm0503.h: fix typo Change-Id: I263d61111544eeb7227e1e0e8f2d14479eae2079 --- M include/osmocom/gsm/gsm0503.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/30/830/1 diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index cf1c976..2da4b16 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -26,7 +26,7 @@ #include -/*! \file conv_gen.h +/*! \file gsm0503.h * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03 */ -- To view, visit https://gerrit.osmocom.org/830 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I263d61111544eeb7227e1e0e8f2d14479eae2079 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Wed Sep 7 16:11:42 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Wed, 7 Sep 2016 16:11:42 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: add RACH, SCH and TCH/AHS definitions Message-ID: Review at https://gerrit.osmocom.org/831 utils/conv_gen.py: add RACH, SCH and TCH/AHS definitions Change-Id: I0ea7151f4e8119a8798a9e129b951559e56b0d93 --- M include/osmocom/gsm/gsm0503.h M src/gsm/libosmogsm.map M utils/conv_gen.py 3 files changed, 212 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/31/831/1 diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index 2da4b16..862dc3f 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -36,10 +36,26 @@ */ extern const struct osmo_conv_code gsm0503_xcch; +/*! \brief structure describing convolutional code RACH + */ +extern const struct osmo_conv_code gsm0503_rach; + +/*! \brief structure describing convolutional code SCH + */ +extern const struct osmo_conv_code gsm0503_sch; + /*! \brief structures describing convolutional codes CS2/3 */ extern const struct osmo_conv_code gsm0503_cs2; extern const struct osmo_conv_code gsm0503_cs3; + +/*! \brief structure describing convolutional code TCH/FR + */ +extern const struct osmo_conv_code gsm0503_tch_fr; + +/*! \brief structure describing convolutional code TCH/HR + */ +extern const struct osmo_conv_code gsm0503_tch_hr; /*! \brief structure describing convolutional code TCH/AFS 12.2 */ @@ -72,3 +88,27 @@ /*! \brief structure describing convolutional code TCH/AFS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_afs_4_75; + +/*! \brief structure describing convolutional code TCH/AHS 7.95 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_95; + +/*! \brief structure describing convolutional code TCH/AHS 7.4 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_7_4; + +/*! \brief structure describing convolutional code TCH/AHS 6.7 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_6_7; + +/*! \brief structure describing convolutional code TCH/AHS 5.9 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_9; + +/*! \brief structure describing convolutional code TCH/AHS 5.15 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_5_15; + +/*! \brief structure describing convolutional code TCH/AHS 4.75 + */ +extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index dc8559f..9eff4d3 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -71,8 +71,12 @@ gsm0502_calc_paging_group; gsm0503_xcch; +gsm0503_rach; +gsm0503_sch; gsm0503_cs2; gsm0503_cs3; +gsm0503_tch_fr; +gsm0503_tch_hr; gsm0503_tch_afs_12_2; gsm0503_tch_afs_10_2; gsm0503_tch_afs_7_95; @@ -81,6 +85,12 @@ gsm0503_tch_afs_5_9; gsm0503_tch_afs_5_15; gsm0503_tch_afs_4_75; +gsm0503_tch_ahs_7_95; +gsm0503_tch_ahs_7_4; +gsm0503_tch_ahs_6_7; +gsm0503_tch_ahs_5_9; +gsm0503_tch_ahs_5_15; +gsm0503_tch_ahs_4_75; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index 5a519bc..9af07b4 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -272,6 +272,22 @@ ] ), + # RACH definition + ConvolutionalCode( + 14, + CCH_poly, + name = "rach", + description = ["RACH convolutional code"] + ), + + # SCH definition + ConvolutionalCode( + 35, + CCH_poly, + name = "sch", + description = ["SCH convolutional code"] + ), + # CS2 definition ConvolutionalCode( 290, @@ -556,7 +572,152 @@ "G6/G6 = 1", "G6/G6 = 1", ] - ) + ), + + # TCH_FR definition + ConvolutionalCode( + 185, + CCH_poly, + name = "tch_fr", + description = ["TCH/F convolutional code"] + ), + + # TCH_HR definition + ConvolutionalCode( + 98, + [ + ( G4, 1 ), + ( G5, 1 ), + ( G6, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, + 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, + 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, + 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214, + 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250, + 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295, + 298, 301, 304, 307, 310, -1, + ], + name = "tch_hr", + description = ["TCH/H convolutional code"] + ), + + # TCH_AHS_7_95 definition + ConvolutionalCode( + 129, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43, + 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95, + 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151, + 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191, + 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221, + 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251, + 255, 257, 259, 261, 263, 265, -1, + ], + name = "tch_ahs_7_95", + description = ["TCH/AHS 7.95 kbits convolutional code"] + ), + + # TCH_AHS_7_4 definition + ConvolutionalCode( + 126, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55, + 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119, + 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, + 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, + 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251, + 253, 255, 257, 259, -1, + ], + name = "tch_ahs_7_4", + description = ["TCH/AHS 7.4 kbits convolutional code"] + ), + + # TCH_AHS_6_7 definition + ConvolutionalCode( + 116, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, + 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189, + 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231, + 233, 235, 237, 239, -1, + ], + name = "tch_ahs_6_7", + description = ["TCH/AHS 6.7 kbits convolutional code"] + ), + + # TCH_AHS_5_9 definition + ConvolutionalCode( + 108, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211, + 215, 219, 221, 223, -1, + ], + name = "tch_ahs_5_9", + description = ["TCH/AHS 5.9 kbits convolutional code"] + ), + + # TCH_AHS_5_15 definition + ConvolutionalCode( + 97, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33, + 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93, + 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159, + 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, + 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, + 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261, + 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289, + 291, 294, 295, 297, 298, 300, 301, -1, + ], + name = "tch_ahs_5_15", + description = ["TCH/AHS 5.15 kbits convolutional code"] + ), + + # TCH_AHS_4_75 definition + ConvolutionalCode( + 89, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34, + 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, + 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166, + 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, + 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256, + 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283, + 284, -1, + ], + name = "tch_ahs_4_75", + description = ["TCH/AHS 4.75 kbits convolutional code"] + ), ] if __name__ == '__main__': -- To view, visit https://gerrit.osmocom.org/831 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0ea7151f4e8119a8798a9e129b951559e56b0d93 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 8 07:13:08 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 8 Sep 2016 07:13:08 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#3). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 7 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/3 diff --git a/src/tbf.cpp b/src/tbf.cpp index 49968dd..8570260 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -375,6 +375,9 @@ return -rc; } + if (this->is_egprs_enabled()) + this->calc_egprs_window_size(); + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..e74c676 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1814,17 +1814,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..b32aff1 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6374,7 +6374,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 8 07:13:09 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 8 Sep 2016 07:13:09 +0000 Subject: [PATCH] osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size Message-ID: Review at https://gerrit.osmocom.org/832 Refactoring: New function to calculate EGPRS DL window size New function is added to calculate the DL EGPRS window size Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Related: OS#1808 --- M src/tbf.cpp M src/tbf.h 2 files changed, 23 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/1 diff --git a/src/tbf.cpp b/src/tbf.cpp index 1fc1aef..49968dd 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -780,20 +780,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->calc_egprs_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); @@ -1246,3 +1234,23 @@ { return ts == control_ts; } + +void gprs_rlcmac_tbf::calc_egprs_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + window()->set_ws(ws); +} diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..0013520 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -155,6 +155,7 @@ bool is_egprs_enabled() const; void enable_egprs(); void disable_egprs(); + void calc_egprs_window_size(); /* attempt to make things a bit more fair */ void rotate_in_list(); -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 8 07:42:53 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 8 Sep 2016 07:42:53 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 3: Hi Neels and Holger, I have uploaded 2 patches as per your suggestion for keeping refactoring and actual fix. please review the same. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 8 11:09:54 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 8 Sep 2016 11:09:54 +0000 Subject: [PATCH] libosmocore[master]: comment: */ports.h: hint at wiki page and indicate some used... Message-ID: Review at https://gerrit.osmocom.org/833 comment: */ports.h: hint at wiki page and indicate some used ports Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 6 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/833/1 diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index c89bbe3..67ea711 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -1,10 +1,13 @@ #pragma once -/* TCP port numbers used for CTRL interfaces in osmocom projects */ +/* TCP port numbers used for CTRL interfaces in osmocom projects. See also: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers */ #define OSMO_CTRL_PORT_BTS 4238 #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 #define OSMO_CTRL_PORT_GGSN 4252 +/* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 +/* 4256 used by VTY interface */ diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 75b8044..74edc82 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -1,6 +1,7 @@ #pragma once -/* TCP port numbers used for VTY interfaces in osmocom projects */ +/* TCP port numbers used for VTY interfaces in osmocom projects. See also: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers */ /* 4238 used by osmo-bts control interface */ #define OSMO_VTY_PORT_PCU 4240 /* also: osmo_pcap_client */ -- To view, visit https://gerrit.osmocom.org/833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 8 11:09:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 8 Sep 2016 11:09:55 +0000 Subject: [PATCH] libosmocore[master]: fix GGSN Ctrl port to 4257 Message-ID: Review at https://gerrit.osmocom.org/834 fix GGSN Ctrl port to 4257 Also comment on usage in vty/ports.h. 4253 used to collide with the sysmobts-mgr VTY port. Note, openggsn does not actually have a Ctrl interface yet. Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/34/834/1 diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index 67ea711..70a4ce9 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -7,7 +7,7 @@ #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 -#define OSMO_CTRL_PORT_GGSN 4252 /* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 /* 4256 used by VTY interface */ +#define OSMO_CTRL_PORT_GGSN 4257 diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 74edc82..5b18099 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -18,3 +18,4 @@ #define OSMO_VTY_PORT_CSCN 4254 /* 4255 used by control interface */ #define OSMO_VTY_PORT_MNCC_SIP 4256 +/* 4257 used by control interface */ -- To view, visit https://gerrit.osmocom.org/834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 8 13:51:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 8 Sep 2016 13:51:15 +0000 Subject: [PATCH] osmo-iuh[master]: RAB Assign for voice: heed the x213 nsap flag Message-ID: Review at https://gerrit.osmocom.org/835 RAB Assign for voice: heed the x213 nsap flag Add use_x213_nsap arg to ranap_new_msg_rab_assign_voice() and new_transp_info_rtp(). Pass this to new_transp_layer_addr() to compose 32bit addresses when use_x213_nsap == false. This is analogous to ranap_new_msg_rab_assign_data(). Particularly, the ip.access nano3G does not accept x213 NSAP 56bit addresses, so we want to send 32bit addresses there. Change-Id: I0c3c95d709c8a2b1c48d7a187faca34102226329 --- M include/osmocom/ranap/ranap_msg_factory.h M src/ranap_msg_factory.c M src/tests/test-ranap.c 3 files changed, 12 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/35/835/1 diff --git a/include/osmocom/ranap/ranap_msg_factory.h b/include/osmocom/ranap/ranap_msg_factory.h index 9639881..120c6e6 100644 --- a/include/osmocom/ranap/ranap_msg_factory.h +++ b/include/osmocom/ranap/ranap_msg_factory.h @@ -32,7 +32,9 @@ struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause); /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ -struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port); +struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, + uint16_t rtp_port, + bool use_x213_nsap); /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data) */ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 401ef4e..695a6be 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -647,7 +647,8 @@ out->bits_unused = 0; } -static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port) +static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port, + bool use_x213_nsap) { RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); uint8_t binding_id[4]; @@ -661,7 +662,7 @@ binding_id[3] = 1; #endif - new_transp_layer_addr(&tli->transportLayerAddress, ip, 1); + new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID, (const char *) binding_id, sizeof(binding_id)); @@ -710,7 +711,9 @@ } /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ -struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port) +struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, + uint16_t rtp_port, + bool use_x213_nsap) { RANAP_ProtocolIE_FieldPair_t *pair; RANAP_RAB_AssignmentRequestIEs_t ies; @@ -731,7 +734,8 @@ //first.nAS_SynchronisationIndicator = FIXME; first.rAB_Parameters = new_rab_par_voice(); first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */ - first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port); + first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port, + use_x213_nsap); /* put together the 'Second' part */ RANAP_RAB_SetupOrModifyItemSecond_t second; diff --git a/src/tests/test-ranap.c b/src/tests/test-ranap.c index 7b1f3bf..ce01b96 100644 --- a/src/tests/test-ranap.c +++ b/src/tests/test-ranap.c @@ -148,7 +148,7 @@ msgb_free(msg); printf("\n==> RAB ASSIGNMENT COMMAND (VOICE)\n"); - msg = ranap_new_msg_rab_assign_voice(1, rtp_ip, rtp_port); + msg = ranap_new_msg_rab_assign_voice(1, rtp_ip, rtp_port, 1); if (msg) printf("%s\n", msgb_hexdump(msg)); msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/835 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0c3c95d709c8a2b1c48d7a187faca34102226329 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 8 15:22:12 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 8 Sep 2016 15:22:12 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: fix some typos Message-ID: Review at https://gerrit.osmocom.org/836 utils/conv_gen.py: fix some typos Change-Id: I3327b92715744af4ef61496ef0121555d9d24799 --- M utils/conv_gen.py 1 file changed, 6 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/36/836/1 diff --git a/utils/conv_gen.py b/utils/conv_gen.py index 9af07b4..f3b3764 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -39,7 +39,7 @@ self.name = name self.description = description - # Handle polynoms (and check for recursion) + # Handle polynomials (and check for recursion) self.polys = [(1, 1) if x[0] == x[1] else x for x in polys] # Determine the polynomial degree @@ -51,11 +51,11 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: " - "Can't have multiple different divider polynoms!") + raise ValueError("Bad polynomials: " + "Can't have multiple different divider polynomials!") if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: " + raise ValueError("Bad polynomials: " "Can't have a '1' divider with a non '1' dividend " "in a recursive code") @@ -87,7 +87,7 @@ src = (ns & 1) | (state << 1) - # Scan polynoms + # Scan polynomials rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: @@ -106,7 +106,7 @@ src = (ns & 1) | (state << 1) - # Scan polynoms + # Scan polynomials rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: -- To view, visit https://gerrit.osmocom.org/836 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3327b92715744af4ef61496ef0121555d9d24799 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 8 15:22:12 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 8 Sep 2016 15:22:12 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions Message-ID: Review at https://gerrit.osmocom.org/837 utils/conv_gen.py: add EDGE MCS 1-9 definitions Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 --- M include/osmocom/gsm/gsm0503.h M src/gsm/libosmogsm.map M utils/conv_gen.py 3 files changed, 301 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/37/837/1 diff --git a/include/osmocom/gsm/gsm0503.h b/include/osmocom/gsm/gsm0503.h index 862dc3f..de28ad2 100644 --- a/include/osmocom/gsm/gsm0503.h +++ b/include/osmocom/gsm/gsm0503.h @@ -112,3 +112,63 @@ /*! \brief structure describing convolutional code TCH/AHS 4.75 */ extern const struct osmo_conv_code gsm0503_tch_ahs_4_75; + +/*! \brief structure describing convolutional code EDGE MCS-1 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-1 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-1 + */ +extern const struct osmo_conv_code gsm0503_mcs1; + +/*! \brief structure describing convolutional code EDGE MCS-2 + */ +extern const struct osmo_conv_code gsm0503_mcs2; + +/*! \brief structure describing convolutional code EDGE MCS-3 + */ +extern const struct osmo_conv_code gsm0503_mcs3; + +/*! \brief structure describing convolutional code EDGE MCS-4 + */ +extern const struct osmo_conv_code gsm0503_mcs4; + +/*! \brief structure describing convolutional code EDGE MCS-5 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-5 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-5 + */ +extern const struct osmo_conv_code gsm0503_mcs5; + +/*! \brief structure describing convolutional code EDGE MCS-6 + */ +extern const struct osmo_conv_code gsm0503_mcs6; + +/*! \brief structure describing convolutional code EDGE MCS-7 DL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-7 UL HDR + */ +extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr; + +/*! \brief structure describing convolutional code EDGE MCS-7 + */ +extern const struct osmo_conv_code gsm0503_mcs7; + +/*! \brief structure describing convolutional code EDGE MCS-8 + */ +extern const struct osmo_conv_code gsm0503_mcs8; + +/*! \brief structure describing convolutional code EDGE MCS-9 + */ +extern const struct osmo_conv_code gsm0503_mcs9; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 9eff4d3..a83f92c 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -91,6 +91,21 @@ gsm0503_tch_ahs_5_9; gsm0503_tch_ahs_5_15; gsm0503_tch_ahs_4_75; +gsm0503_mcs1_dl_hdr; +gsm0503_mcs1_ul_hdr; +gsm0503_mcs1; +gsm0503_mcs2; +gsm0503_mcs3; +gsm0503_mcs4; +gsm0503_mcs5_dl_hdr; +gsm0503_mcs5_ul_hdr; +gsm0503_mcs5; +gsm0503_mcs6; +gsm0503_mcs7_dl_hdr; +gsm0503_mcs7_ul_hdr; +gsm0503_mcs7; +gsm0503_mcs8; +gsm0503_mcs9; gsm0808_att_tlvdef; gsm0808_bssap_name; diff --git a/utils/conv_gen.py b/utils/conv_gen.py index f3b3764..1bcbd6a 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -28,12 +28,13 @@ class ConvolutionalCode(object): def __init__(self, block_len, polys, name, - description = None, puncture = []): + description = None, puncture = [], term_type = None): # Save simple params self.block_len = block_len self.k = 1 self.puncture = puncture self.rate_inv = len(polys) + self.term_type = term_type # Infos self.name = name @@ -227,6 +228,8 @@ print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k print >>fi, "\t.len = %d," % self.block_len + if self.term_type is not None: + print >>fi, "\t.term = %s," % self.term_type print >>fi, "\t.next_output = %s_output," % self.name print >>fi, "\t.next_state = %s_state," % self.name if self.recursive: @@ -256,6 +259,12 @@ CCH_poly = [ ( G0, 1 ), ( G1, 1 ), +] + +MCS_poly = [ + ( G4, 1 ), + ( G7, 1 ), + ( G5, 1 ), ] conv_codes = [ @@ -718,6 +727,222 @@ name = "tch_ahs_4_75", description = ["TCH/AHS 4.75 kbits convolutional code"] ), + + # EDGE MCS1_DL_HDR definition + ConvolutionalCode( + 36, + MCS_poly, + name = "mcs1_dl_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-1 DL header convolutional code:", + "42 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS1_UL_HDR definition + ConvolutionalCode( + 39, + MCS_poly, + name = "mcs1_ul_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-1 UL header convolutional code:", + "45 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS1 definition + ConvolutionalCode( + 190, + MCS_poly, + name = "mcs1", + description = [ + "EDGE MCS-1 data convolutional code:", + "196 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS2 definition + ConvolutionalCode( + 238, + MCS_poly, + name = "mcs2", + description = [ + "EDGE MCS-2 data convolutional code:", + "244 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS3 definition + ConvolutionalCode( + 310, + MCS_poly, + name = "mcs3", + description = [ + "EDGE MCS-3 data convolutional code:", + "316 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS4 definition + ConvolutionalCode( + 366, + MCS_poly, + name = "mcs4", + description = [ + "EDGE MCS-4 data convolutional code:", + "372 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS5_DL_HDR definition + ConvolutionalCode( + 33, + MCS_poly, + name = "mcs5_dl_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-5 DL header convolutional code:", + "39 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS5_UL_HDR definition + ConvolutionalCode( + 45, + MCS_poly, + name = "mcs5_ul_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-5 UL header convolutional code:", + "51 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS5 definition + ConvolutionalCode( + 462, + MCS_poly, + name = "mcs5", + description = [ + "EDGE MCS-5 data convolutional code:", + "468 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS6 definition + ConvolutionalCode( + 606, + MCS_poly, + name = "mcs6", + description = [ + "EDGE MCS-6 data convolutional code:", + "612 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS7_DL_HDR definition + ConvolutionalCode( + 45, + MCS_poly, + name = "mcs7_dl_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-7 DL header convolutional code:", + "51 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS7_UL_HDR definition + ConvolutionalCode( + 54, + MCS_poly, + name = "mcs7_ul_hdr", + term_type = "CONV_TERM_TAIL_BITING", + description = [ + "EDGE MCS-7 UL header convolutional code:", + "60 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS7 definition + ConvolutionalCode( + 462, + MCS_poly, + name = "mcs7", + description = [ + "EDGE MCS-7 data convolutional code:", + "468 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS8 definition + ConvolutionalCode( + 558, + MCS_poly, + name = "mcs8", + description = [ + "EDGE MCS-8 data convolutional code:", + "564 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), + + # EDGE MCS9 definition + ConvolutionalCode( + 606, + MCS_poly, + name = "mcs9", + description = [ + "EDGE MCS-9 data convolutional code:", + "612 bits blocks, rate 1/3, k = 7", + "G4 = 1 + D2 + D3 + D5 + D6", + "G7 = 1 + D + D2 + D3 + D6", + "G5 = 1 + D + D4 + D6" + ] + ), ] if __name__ == '__main__': -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 8 16:44:56 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Thu, 8 Sep 2016 16:44:56 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 3: -Code-Review -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 8 23:05:12 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Thu, 8 Sep 2016 23:05:12 +0000 Subject: [PATCH] openbsc[master]: Consistenly format variables in */Makefile.am files Message-ID: Review at https://gerrit.osmocom.org/838 Consistenly format variables in */Makefile.am files Change-Id: Ifa21513c007072314097b7bec188579972dc1694 --- M openbsc/Makefile.am M openbsc/doc/Makefile.am M openbsc/doc/examples/Makefile.am M openbsc/include/Makefile.am M openbsc/include/openbsc/Makefile.am M openbsc/src/Makefile.am M openbsc/src/gprs/Makefile.am M openbsc/src/ipaccess/Makefile.am M openbsc/src/libbsc/Makefile.am M openbsc/src/libcommon/Makefile.am M openbsc/src/libfilter/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/src/libmgcp/Makefile.am M openbsc/src/libmsc/Makefile.am M openbsc/src/libtrau/Makefile.am M openbsc/src/osmo-bsc/Makefile.am M openbsc/src/osmo-bsc_mgcp/Makefile.am M openbsc/src/osmo-bsc_nat/Makefile.am M openbsc/src/osmo-nitb/Makefile.am M openbsc/src/utils/Makefile.am M openbsc/tests/Makefile.am M openbsc/tests/abis/Makefile.am M openbsc/tests/bsc-nat/Makefile.am M openbsc/tests/bsc/Makefile.am M openbsc/tests/channel/Makefile.am M openbsc/tests/db/Makefile.am M openbsc/tests/gbproxy/Makefile.am M openbsc/tests/gsm0408/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mgcp/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/oap/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/smpp/Makefile.am M openbsc/tests/subscr/Makefile.am M openbsc/tests/trau/Makefile.am M openbsc/tests/xid/Makefile.am 37 files changed, 1,526 insertions(+), 502 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/838/1 diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am index 8696eb4..6f76d33 100644 --- a/openbsc/Makefile.am +++ b/openbsc/Makefile.am @@ -1,9 +1,18 @@ -AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 +AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 $(NULL) -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = doc include src tests +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -pkgconfigdir = $(libdir)/pkgconfig +SUBDIRS = \ + doc \ + include \ + src \ + tests \ + $(NULL) + +pkgconfigdir = $(libdir)/pkgconfig $(NULL) pkgconfig_DATA = openbsc.pc BUILT_SOURCES = $(top_srcdir)/.version diff --git a/openbsc/doc/Makefile.am b/openbsc/doc/Makefile.am index aee2d7b..8acb8f8 100644 --- a/openbsc/doc/Makefile.am +++ b/openbsc/doc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = examples +SUBDIRS = \ + examples \ + $(NULL) diff --git a/openbsc/doc/examples/Makefile.am b/openbsc/doc/examples/Makefile.am index 8f14fdc..530c3fa 100644 --- a/openbsc/doc/examples/Makefile.am +++ b/openbsc/doc/examples/Makefile.am @@ -1,4 +1,3 @@ - CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' dist-hook: diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index 4596b6e..8ac6729 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,8 @@ -SUBDIRS = openbsc +SUBDIRS = \ + openbsc \ + $(NULL) -noinst_HEADERS = mISDNif.h compat_af_isdn.h +noinst_HEADERS = \ + mISDNif.h \ + compat_af_isdn.h \ + $(NULL) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..1cd729a 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -1,25 +1,87 @@ -noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ - gsm_subscriber.h gsm_04_11.h debug.h signal.h \ - misdn.h chan_alloc.h paging.h ctrl.h \ - trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ - silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h \ - vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \ - handover_decision.h rrlp.h \ - crc24.h gprs_llc.h gprs_gmm.h \ - gb_proxy.h gprs_sgsn.h sgsn.h \ - auth.h osmo_msc.h bsc_msc.h bsc_nat.h \ - osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \ - osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.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_client.h bsc_msg_filter.h \ - oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ +noinst_HEADERS = \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bss.h \ + chan_alloc.h \ + crc24.h \ + ctrl.h \ + db.h \ + debug.h \ + e1_config.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_gsup_client.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp.h \ + gprs_utils.h \ + gsm_04_08.h \ + gsm_04_11.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + gtphub.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ iu.h + meas_feed.h \ + meas_rep.h \ + mgcp.h \ + mgcp_internal.h \ + mgcp_transcode.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + nat_rewrite_trie.h \ + network_listen.h \ + oap.h \ + oap_messages.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_msc_data.h \ + osmux.h \ + paging.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + smpp.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + token_auth.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + $(NULL) -openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h -openbscdir = $(includedir)/openbsc +openbsc_HEADERS = \ + bsc_api.h \ + gsm_04_08.h \ + meas_rep.h \ + $(NULL) + +openbscdir = \ + $(includedir)/openbsc \ + $(NULL) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 4aa880f..7edfe7f 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -1,22 +1,59 @@ -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) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) # Libraries -SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter +SUBDIRS = \ + libcommon \ + libmgcp \ + libbsc \ + libmsc \ + libtrau \ + libfilter \ + $(NULL) # Conditional Libraries if BUILD_IU -SUBDIRS += libiu +SUBDIRS += \ + libiu \ + $(NULL) endif # Programs -SUBDIRS += osmo-nitb osmo-bsc_mgcp utils ipaccess gprs +SUBDIRS += \ + osmo-nitb \ + osmo-bsc_mgcp \ + utils \ + ipaccess \ + gprs \ + $(NULL) # Conditional Programs if BUILD_NAT -SUBDIRS += osmo-bsc_nat +SUBDIRS += \ + osmo-bsc_nat \ + $(NULL) endif + if BUILD_BSC -SUBDIRS += osmo-bsc +SUBDIRS += \ + osmo-bsc \ + $(NULL) endif diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..8cb4601 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -1,50 +1,132 @@ -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) \ - $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) + if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(NULL) -bin_PROGRAMS = osmo-gbproxy +bin_PROGRAMS = \ + osmo-gbproxy \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -bin_PROGRAMS += osmo-sgsn osmo-gtphub +bin_PROGRAMS += \ + osmo-sgsn \ + osmo-gtphub \ + $(NULL) endif endif -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) $(LIBCRYPTO_LIBS) -lrt +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 \ + $(NULL) -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_utils.c gprs_gsup_client.c \ - sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +osmo_gbproxy_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) + +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_utils.c \ + gprs_gsup_client.c \ + sgsn_cdr.c \ + sgsn_ares.c \ + oap.c \ + oap_messages.c \ + gprs_llc_xid.c \ + $(NULL) + +osmo_sgsn_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) + if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif -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 +osmo_gtphub_SOURCES = \ + gtphub_main.c \ + gtphub.c \ + gtphub_sock.c \ + gtphub_ares.c \ + gtphub_vty.c \ + sgsn_ares.c \ + gprs_utils.c \ + $(NULL) + +osmo_gtphub_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCARES_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am index 9acc0f7..f527e4d 100644 --- a/openbsc/src/ipaccess/Makefile.am +++ b/openbsc/src/ipaccess/Makefile.am @@ -1,26 +1,65 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = abisip-find ipaccess-config ipaccess-proxy +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -abisip_find_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) -abisip_find_SOURCES = abisip-find.c +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -ipaccess_config_SOURCES = ipaccess-config.c ipaccess-firmware.c network_listen.c +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +bin_PROGRAMS = \ + abisip-find \ + ipaccess-config \ + ipaccess-proxy \ + $(NULL) + +abisip_find_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) + +abisip_find_SOURCES = \ + abisip-find.c \ + $(NULL) + +ipaccess_config_SOURCES = \ + ipaccess-config.c \ + ipaccess-firmware.c \ + network_listen.c \ + $(NULL) # FIXME: resolve the bogus dependencies patched around here: ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBCRYPT) $(OSMO_LIBS) + $(LIBCRYPT) \ + $(OSMO_LIBS) \ + $(NULL) -ipaccess_proxy_SOURCES = ipaccess-proxy.c -ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ +ipaccess_proxy_SOURCES = \ + ipaccess-proxy.c \ + $(NULL) + +ipaccess_proxy_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) + $(OSMO_LIBS) \ + $(NULL) diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am index fd8de0e..925ada9 100644 --- a/openbsc/src/libbsc/Makefile.am +++ b/openbsc/src/libbsc/Makefile.am @@ -1,28 +1,52 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libbsc.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libbsc_a_SOURCES = abis_nm.c abis_nm_vty.c \ - abis_om2000.c abis_om2000_vty.c \ - abis_rsl.c bsc_rll.c \ - paging.c \ - bts_ericsson_rbs2000.c \ - bts_ipaccess_nanobts.c \ - bts_siemens_bs11.c \ - bts_nokia_site.c \ - bts_unknown.c \ - bts_sysmobts.c \ - chan_alloc.c \ - handover_decision.c handover_logic.c meas_rep.c \ - rest_octets.c system_information.c \ - e1_config.c \ - bsc_api.c bsc_msc.c bsc_vty.c \ - gsm_04_08_utils.c \ - bsc_init.c bts_init.c bsc_rf_ctrl.c \ - arfcn_range_encode.c bsc_ctrl_commands.c \ - bsc_ctrl_lookup.c \ - net_init.c \ - bsc_dyn_ts.c +noinst_LIBRARIES = \ + libbsc.a \ + $(NULL) + +libbsc_a_SOURCES = abis_nm.c \ + abis_nm_vty.c \ + abis_om2000.c \ + abis_om2000_vty.c \ + abis_rsl.c \ + bsc_rll.c \ + paging.c \ + bts_ericsson_rbs2000.c \ + bts_ipaccess_nanobts.c \ + bts_siemens_bs11.c \ + bts_nokia_site.c \ + bts_unknown.c \ + bts_sysmobts.c \ + chan_alloc.c \ + handover_decision.c \ + handover_logic.c \ + meas_rep.c \ + rest_octets.c \ + system_information.c \ + e1_config.c \ + bsc_api.c \ + bsc_msc.c bsc_vty.c \ + gsm_04_08_utils.c \ + bsc_init.c \ + bts_init.c \ + bsc_rf_ctrl.c \ + arfcn_range_encode.c \ + bsc_ctrl_commands.c \ + bsc_ctrl_lookup.c \ + net_init.c \ + bsc_dyn_ts.c \ + $(NULL) diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am index 75f40ee..e508b68 100644 --- a/openbsc/src/libcommon/Makefile.am +++ b/openbsc/src/libcommon/Makefile.am @@ -1,9 +1,29 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libcommon.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \ - gsm_data_shared.c socket.c talloc_ctx.c \ - gsm_subscriber_base.c +noinst_LIBRARIES = \ + libcommon.a \ + $(NULL) + +libcommon_a_SOURCES = \ + bsc_version.c \ + common_vty.c \ + debug.c \ + gsm_data.c \ + gsm_data_shared.c \ + socket.c \ + talloc_ctx.c \ + gsm_subscriber_base.c \ + $(NULL) diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am index ed3cd43..116e124 100644 --- a/openbsc/src/libfilter/Makefile.am +++ b/openbsc/src/libfilter/Makefile.am @@ -1,11 +1,26 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libfilter.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libfilter.a \ + $(NULL) libfilter_a_SOURCES = \ - bsc_msg_filter.c \ - bsc_msg_acc.c \ - bsc_msg_vty.c + bsc_msg_filter.c \ + bsc_msg_acc.c \ + bsc_msg_vty.c \ + $(NULL) diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..24bf0f4 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,10 +1,28 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libiu.a +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) -libiu_a_SOURCES = iu.c iu_vty.c +noinst_LIBRARIES = \ + libiu.a \ + $(NULL) + +libiu_a_SOURCES = \ + iu.c \ + iu_vty.c \ + $(NULL) diff --git a/openbsc/src/libmgcp/Makefile.am b/openbsc/src/libmgcp/Makefile.am index 4403d60..ee9c275 100644 --- a/openbsc/src/libmgcp/Makefile.am +++ b/openbsc/src/libmgcp/Makefile.am @@ -1,16 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(COVERAGE_LDFLAGS) $(LIBBCG729_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libmgcp.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_HEADERS = g711common.h +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBBCG729_LIBS) \ + $(NULL) -libmgcp_a_SOURCES = mgcp_protocol.c mgcp_network.c mgcp_vty.c mgcp_osmux.c \ - mgcp_sdp.c +noinst_LIBRARIES = \ + libmgcp.a \ + $(NULL) + +noinst_HEADERS = \ + g711common.h \ + $(NULL) + +libmgcp_a_SOURCES = \ + mgcp_protocol.c \ + mgcp_network.c \ + mgcp_vty.c \ + mgcp_osmux.c \ + mgcp_sdp.c \ + $(NULL) if BUILD_MGCP_TRANSCODING - libmgcp_a_SOURCES += mgcp_transcode.c +libmgcp_a_SOURCES += \ + mgcp_transcode.c \ + $(NULL) endif diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index 5195890..d6c1473 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -1,27 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_feed.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libmsc.a +noinst_HEADERS = \ + meas_feed.h \ + $(NULL) -libmsc_a_SOURCES = auth.c \ - db.c \ - gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c mncc_builtin.c mncc_sock.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - token_auth.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c ctrl_commands.c meas_feed.c +noinst_LIBRARIES = \ + libmsc.a \ + $(NULL) + +libmsc_a_SOURCES = auth.c \ + db.c \ + gsm_04_08.c \ + gsm_04_11.c \ + gsm_04_11_helper.c \ + gsm_04_80.c \ + gsm_subscriber.c \ + mncc.c \ + mncc_builtin.c \ + mncc_sock.c \ + rrlp.c \ + silent_call.c \ + sms_queue.c \ + token_auth.c \ + ussd.c \ + vty_interface_layer3.c \ + transaction.c \ + osmo_msc.c \ + ctrl_commands.c \ + meas_feed.c \ + $(NULL) if BUILD_SMPP -noinst_HEADERS += smpp_smsc.h -libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c +noinst_HEADERS += \ + smpp_smsc.h \ + $(NULL) + +libmsc_a_SOURCES += \ + smpp_smsc.c \ + smpp_openbsc.c \ + smpp_vty.c \ + smpp_utils.c \ + $(NULL) endif diff --git a/openbsc/src/libtrau/Makefile.am b/openbsc/src/libtrau/Makefile.am index 0fe3a53..5c9d5b1 100644 --- a/openbsc/src/libtrau/Makefile.am +++ b/openbsc/src/libtrau/Makefile.am @@ -1,7 +1,31 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libtrau.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libtrau_a_SOURCES = rtp_proxy.c trau_mux.c trau_upqueue.c +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libtrau.a \ + $(NULL) + +libtrau_a_SOURCES = \ + rtp_proxy.c \ + trau_mux.c \ + trau_upqueue.c \ + $(NULL) diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 4aa1803..328fd50 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -1,13 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc \ + $(NULL) -osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ - osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c +osmo_bsc_SOURCES = \ + osmo_bsc_main.c \ + osmo_bsc_vty.c \ + osmo_bsc_api.c \ + osmo_bsc_grace.c \ + osmo_bsc_msc.c \ + osmo_bsc_sccp.c \ + osmo_bsc_filter.c \ + osmo_bsc_bssap.c \ + osmo_bsc_audio.c \ + osmo_bsc_ctrl.c \ + $(NULL) + # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = \ $(top_builddir)/src/libfilter/libfilter.a \ @@ -16,6 +46,11 @@ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_mgcp/Makefile.am b/openbsc/src/osmo-bsc_mgcp/Makefile.am index a48f24b..9b2f191 100644 --- a/openbsc/src/osmo-bsc_mgcp/Makefile.am +++ b/openbsc/src/osmo-bsc_mgcp/Makefile.am @@ -1,14 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_mgcp +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -osmo_bsc_mgcp_SOURCES = mgcp_main.c +bin_PROGRAMS = \ + osmo-bsc_mgcp \ + $(NULL) + +osmo_bsc_mgcp_SOURCES = \ + mgcp_main.c \ + $(NULL) osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libmgcp/libmgcp.a -lrt \ - $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(LIBBCG729_LIBS) \ - $(LIBRARY_GSM) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_nat/Makefile.am b/openbsc/src/osmo-bsc_nat/Makefile.am index 4a6f74d..6c07d7f 100644 --- a/openbsc/src/osmo-bsc_nat/Makefile.am +++ b/openbsc/src/osmo-bsc_nat/Makefile.am @@ -1,19 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBCRYPTO_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_nat +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc_nat \ + $(NULL) -osmo_bsc_nat_SOURCES = bsc_filter.c bsc_mgcp_utils.c bsc_nat.c bsc_nat_utils.c \ - bsc_nat_vty.c bsc_sccp.c bsc_ussd.c bsc_nat_ctrl.c \ - bsc_nat_rewrite.c bsc_nat_rewrite_trie.c bsc_nat_filter.c +osmo_bsc_nat_SOURCES = \ + bsc_filter.c \ + bsc_mgcp_utils.c \ + bsc_nat.c \ + bsc_nat_utils.c \ + bsc_nat_vty.c \ + bsc_sccp.c \ + bsc_ussd.c \ + bsc_nat_ctrl.c \ + bsc_nat_rewrite.c \ + bsc_nat_rewrite_trie.c \ + bsc_nat_filter.c \ + $(NULL) + osmo_bsc_nat_LDADD = \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libfilter/libfilter.a \ - -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-nitb/Makefile.am b/openbsc/src/osmo-nitb/Makefile.am index 3b7cc8d..7e2782e 100644 --- a/openbsc/src/osmo-nitb/Makefile.am +++ b/openbsc/src/osmo-nitb/Makefile.am @@ -1,18 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = osmo-nitb +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_nitb_SOURCES = bsc_hack.c +bin_PROGRAMS = \ + osmo-nitb \ + $(NULL) + +osmo_nitb_SOURCES = \ + bsc_hack.c \ + $(NULL) + osmo_nitb_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - -ldbi $(LIBCRYPT) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOABIS_LIBS) $(LIBSMPP34_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..e54a93d 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,42 +1,124 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ - $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_db.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = bs11_config isdnsync +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + meas_db.h \ + $(NULL) + +bin_PROGRAMS = \ + bs11_config \ + isdnsync \ + $(NULL) + if HAVE_SQLITE3 -bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db +bin_PROGRAMS += \ + osmo-meas-pcap2db \ + osmo-meas-udp2db \ + $(NULL) endif if HAVE_LIBCDK -bin_PROGRAMS += meas_vis +bin_PROGRAMS += \ + meas_vis \ + $(NULL) endif if BUILD_SMPP -noinst_PROGRAMS = smpp_mirror +noinst_PROGRAMS = \ + smpp_mirror \ + $(NULL) endif -bs11_config_SOURCES = bs11_config.c -bs11_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ +bs11_config_SOURCES = \ + bs11_config.c \ + $(NULL) + +bs11_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) -isdnsync_SOURCES = isdnsync.c +isdnsync_SOURCES = \ + isdnsync.c \ + $(NULL) -smpp_mirror_SOURCES = smpp_mirror.c -smpp_mirror_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) +smpp_mirror_SOURCES = \ + smpp_mirror.c \ + $(NULL) -meas_vis_SOURCES = meas_vis.c -meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses -meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(NULL) -osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c -osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS) -osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_SOURCES = \ + meas_vis.c \ + $(NULL) -osmo_meas_udp2db_SOURCES = meas_udp2db.c meas_db.c -osmo_meas_udp2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(SQLITE3_LIBS) -osmo_meas_udp2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lcdk \ + -lncurses \ + $(NULL) + +meas_vis_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_pcap2db_SOURCES = \ + meas_pcap2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_pcap2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + -lpcap \ + $(NULL) + +osmo_meas_pcap2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_udp2db_SOURCES = \ + meas_udp2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_udp2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +osmo_meas_udp2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..5c9a302 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,21 +1,46 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid +SUBDIRS = \ + gsm0408 \ + db \ + channel \ + mgcp \ + gprs \ + abis \ + gbproxy \ + trau \ + subscr \ + mm_auth \ + xid \ + $(NULL) if BUILD_NAT -SUBDIRS += bsc-nat bsc-nat-trie +SUBDIRS += \ + bsc-nat \ + bsc-nat-trie \ + $(NULL) endif if BUILD_BSC -SUBDIRS += bsc +SUBDIRS += \ + bsc \ + $(NULL) endif if BUILD_SMPP -SUBDIRS += smpp +SUBDIRS += \ + smpp \ + $(NULL) endif if HAVE_LIBGTP -SUBDIRS += gtphub +SUBDIRS += \ + gtphub \ + $(NULL) + if HAVE_LIBCARES -SUBDIRS += sgsn oap +SUBDIRS += \ + sgsn \ + oap \ + $(NULL) endif endif @@ -38,9 +63,22 @@ echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) vty_test_runner.py ctrl_test_runner.py smpp_test_runner.py -TESTSUITE = $(srcdir)/testsuite -DISTCLEANFILES = atconfig +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + vty_test_runner.py \ + ctrl_test_runner.py \ + smpp_test_runner.py \ + $(NULL) + +TESTSUITE = \ + $(srcdir)/testsuite \ + $(NULL) + +DISTCLEANFILES = \ + atconfig \ + $(NULL) if ENABLE_EXT_TESTS python-tests: $(BUILT_SOURCES) diff --git a/openbsc/tests/abis/Makefile.am b/openbsc/tests/abis/Makefile.am index c2e38de..d3f40f2 100644 --- a/openbsc/tests/abis/Makefile.am +++ b/openbsc/tests/abis/Makefile.am @@ -1,17 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = abis_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = abis_test +EXTRA_DIST = \ + abis_test.ok \ + $(NULL) -abis_test_SOURCES = abis_test.c +noinst_PROGRAMS = \ + abis_test \ + $(NULL) + +abis_test_SOURCES = \ + abis_test.c \ + $(NULL) abis_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 26e5500..4c1dac8 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -1,26 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_nat_test.ok bsc_data.c barr.cfg barr_dup.cfg prefixes.csv +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_nat_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_nat_test_SOURCES = bsc_nat_test.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c +EXTRA_DIST = \ + bsc_nat_test.ok \ + bsc_data.c \ + barr.cfg \ + barr_dup.cfg \ + prefixes.csv \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_nat_test \ + $(NULL) + +bsc_nat_test_SOURCES = \ + bsc_nat_test.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c + bsc_nat_test_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) \ - $(LIBOSMOCTRL_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am index 8b786ff..63e13da 100644 --- a/openbsc/tests/bsc/Makefile.am +++ b/openbsc/tests/bsc/Makefile.am @@ -1,18 +1,45 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_test_SOURCES = bsc_test.c \ - $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c -bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) +EXTRA_DIST = \ + bsc_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_test \ + $(NULL) + +bsc_test_SOURCES = \ + bsc_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(NULL) + +bsc_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am index 51b2f83..86cb2cd 100644 --- a/openbsc/tests/channel/Makefile.am +++ b/openbsc/tests/channel/Makefile.am @@ -1,14 +1,33 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = channel_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = channel_test +EXTRA_DIST = \ + channel_test.ok \ + $(NULL) -channel_test_SOURCES = channel_test.c +noinst_PROGRAMS = \ + channel_test \ + $(NULL) + +channel_test_SOURCES = \ + channel_test.c \ + $(NULL) channel_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - -ldbi $(LIBOSMOGSM_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am index be3af5f..14ee3aa 100644 --- a/openbsc/tests/db/Makefile.am +++ b/openbsc/tests/db/Makefile.am @@ -1,17 +1,48 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = db_test.ok db_test.err hlr.sqlite3 +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = db_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -db_test_SOURCES = db_test.c -db_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + hlr.sqlite3 \ + $(NULL) + +noinst_PROGRAMS = \ + db_test \ + $(NULL) + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBCRYPTO_LIBS) -ldbi + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gbproxy/Makefile.am b/openbsc/tests/gbproxy/Makefile.am index 18d77a8..1308bda 100644 --- a/openbsc/tests/gbproxy/Makefile.am +++ b/openbsc/tests/gbproxy/Makefile.am @@ -1,27 +1,54 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gbproxy_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = gbproxy_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -gbproxy_test_SOURCES = gbproxy_test.c +EXTRA_DIST = \ + gbproxy_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + gbproxy_test \ + $(NULL) + +gbproxy_test_SOURCES = \ + gbproxy_test.c \ + $(NULL) + gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes + -Wl,--wrap=RAND_bytes \ + $(NULL) + gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) -lrt + $(top_builddir)/src/gprs/gb_proxy.o \ + $(top_builddir)/src/gprs/gb_proxy_patch.o \ + $(top_builddir)/src/gprs/gb_proxy_peer.o \ + $(top_builddir)/src/gprs/gb_proxy_tlli.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBRARY_DL) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index 79fb9f1..f736557 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -1,12 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -noinst_PROGRAMS = gsm0408_test +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gsm0408_test.ok +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -gsm0408_test_SOURCES = gsm0408_test.c -gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) -ldbi +noinst_PROGRAMS = \ + gsm0408_test \ + $(NULL) + +EXTRA_DIST = \ + gsm0408_test.ok \ + $(NULL) + +gsm0408_test_SOURCES = \ + gsm0408_test.c \ + $(NULL) + +gsm0408_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..654b662 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,24 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) EXTRA_DIST = \ - gtphub_test.ok + gtphub_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = gtphub_test +noinst_PROGRAMS = \ + gtphub_test \ + $(NULL) endif endif -gtphub_test_SOURCES = gtphub_test.c +gtphub_test_SOURCES = \ + gtphub_test.c \ + $(NULL) + gtphub_test_LDFLAGS = \ - -Wl,--wrap=gtphub_resolve_ggsn_addr \ - -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write + -Wl,--wrap=gtphub_resolve_ggsn_addr \ + -Wl,--wrap=gtphub_ares_init \ + -Wl,--wrap=gtphub_write \ + $(NULL) gtphub_test_LDADD = \ - $(top_builddir)/src/gprs/gtphub.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt - + $(top_builddir)/src/gprs/gtphub.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(LIBOSMOCORE_LIBS) \ + -lgtp \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 82d6ac6..77cb6b7 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -1,30 +1,73 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_FLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir) \ + $(NULL) -EXTRA_DIST = mgcp_test.ok mgcp_transcoding_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_FLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = mgcp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + mgcp_test.ok \ + mgcp_transcoding_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + mgcp_test \ + $(NULL) if BUILD_MGCP_TRANSCODING -noinst_PROGRAMS += mgcp_transcoding_test +noinst_PROGRAMS += \ + mgcp_transcoding_test \ + $(NULL) endif -mgcp_test_SOURCES = mgcp_test.c +mgcp_test_SOURCES = \ + mgcp_test.c \ + $(NULL) -mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) +mgcp_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + -lrt \ + -lm \ + $(NULL) -mgcp_transcoding_test_SOURCES = mgcp_transcoding_test.c +mgcp_transcoding_test_SOURCES = \ + mgcp_transcoding_test.c \ + $(NULL) mgcp_transcoding_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmgcp/libmgcp.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBBCG729_LIBS) -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) $(LIBRARY_GSM) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + -lm \ + $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..9db9716 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -1,21 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -noinst_PROGRAMS = mm_auth_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(NULL) -EXTRA_DIST = mm_auth_test.ok +noinst_PROGRAMS = \ + mm_auth_test \ + $(NULL) -mm_auth_test_SOURCES = mm_auth_test.c +EXTRA_DIST = \ + mm_auth_test.ok \ + $(NULL) + +mm_auth_test_SOURCES = \ + mm_auth_test.c \ + $(NULL) mm_auth_test_LDFLAGS = \ - -Wl,--wrap=db_get_authinfo_for_subscr \ - -Wl,--wrap=db_get_lastauthtuple_for_subscr \ - -Wl,--wrap=db_sync_lastauthtuple_for_subscr + -Wl,--wrap=db_get_authinfo_for_subscr \ + -Wl,--wrap=db_get_lastauthtuple_for_subscr \ + -Wl,--wrap=db_sync_lastauthtuple_for_subscr \ + $(NULL) -mm_auth_test_LDADD = $(top_builddir)/src/libmsc/libmsc.a \ +mm_auth_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/oap/Makefile.am b/openbsc/tests/oap/Makefile.am index 538e178..f1a7ccf 100644 --- a/openbsc/tests/oap/Makefile.am +++ b/openbsc/tests/oap/Makefile.am @@ -1,22 +1,37 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = oap_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + oap_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = oap_test +noinst_PROGRAMS = \ + oap_test \ + $(NULL) endif endif -oap_test_SOURCES = oap_test.c +oap_test_SOURCES = \ + oap_test.c \ + $(NULL) oap_test_LDADD = \ - $(top_builddir)/src/gprs/oap.o \ - $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - -lrt + $(top_builddir)/src/gprs/oap.o \ + $(top_builddir)/src/gprs/oap_messages.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lrt diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..46c6089 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,52 +1,78 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) + if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -EXTRA_DIST = sgsn_test.ok +EXTRA_DIST = \ + sgsn_test.ok \ + $(NULL) -noinst_PROGRAMS = sgsn_test +noinst_PROGRAMS = \ + sgsn_test \ + $(NULL) -sgsn_test_SOURCES = sgsn_test.c +sgsn_test_SOURCES = \ + sgsn_test.c \ + $(NULL) + sgsn_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes \ - -Wl,--wrap=sgsn_update_subscriber_data \ - -Wl,--wrap=gprs_subscr_request_update_location \ - -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gprs_gsup_client_send + -Wl,--wrap=RAND_bytes \ + -Wl,--wrap=sgsn_update_subscriber_data \ + -Wl,--wrap=gprs_subscr_request_update_location \ + -Wl,--wrap=gprs_subscr_request_auth_info \ + -Wl,--wrap=gprs_gsup_client_send \ + $(NULL) sgsn_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/gprs_llc.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_sndcp.o \ - $(top_builddir)/src/gprs/gprs_gmm.o \ - $(top_builddir)/src/gprs/gprs_sgsn.o \ - $(top_builddir)/src/gprs/sgsn_vty.o \ - $(top_builddir)/src/gprs/sgsn_libgtp.o \ - $(top_builddir)/src/gprs/sgsn_auth.o \ - $(top_builddir)/src/gprs/sgsn_ares.o \ - $(top_builddir)/src/gprs/gprs_gsup_client.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/gprs/gprs_subscriber.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/oap.o \ - $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/gprs_llc.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_sndcp.o \ + $(top_builddir)/src/gprs/gprs_gmm.o \ + $(top_builddir)/src/gprs/gprs_sgsn.o \ + $(top_builddir)/src/gprs/sgsn_vty.o \ + $(top_builddir)/src/gprs/sgsn_libgtp.o \ + $(top_builddir)/src/gprs/sgsn_auth.o \ + $(top_builddir)/src/gprs/sgsn_ares.o \ + $(top_builddir)/src/gprs/gprs_gsup_client.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/gprs/gprs_subscriber.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/oap.o \ + $(top_builddir)/src/gprs/oap_messages.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp \ + -lrt \ + $(NULL) + if BUILD_IU sgsn_test_LDADD += \ - $(top_builddir)/src/libiu/libiu.a \ - $(LIBOSMORANAP_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMORANAP_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif - diff --git a/openbsc/tests/smpp/Makefile.am b/openbsc/tests/smpp/Makefile.am index aab4de9..fa09aa2 100644 --- a/openbsc/tests/smpp/Makefile.am +++ b/openbsc/tests/smpp/Makefile.am @@ -1,13 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/libmsc \ + $(NULL) -EXTRA_DIST = smpp_test.ok smpp_test.err +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = smpp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -smpp_test_SOURCES = smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c +EXTRA_DIST = \ + smpp_test.ok \ + smpp_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + smpp_test \ + $(NULL) + +smpp_test_SOURCES = \ + smpp_test.c \ + $(top_builddir)/src/libmsc/smpp_utils.c \ + $(NULL) + smpp_test_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/subscr/Makefile.am b/openbsc/tests/subscr/Makefile.am index 4f96dc9..a2c7e7e 100644 --- a/openbsc/tests/subscr/Makefile.am +++ b/openbsc/tests/subscr/Makefile.am @@ -1,18 +1,42 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = subscr_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = subscr_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -subscr_test_SOURCES = subscr_test.c -subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -# -ldbi +EXTRA_DIST = \ + subscr_test.ok \ + $(NULL) +noinst_PROGRAMS = \ + subscr_test \ + $(NULL) + +subscr_test_SOURCES = \ + subscr_test.c \ + $(NULL) + +subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(NULL) diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am index cc1b4ef..9dfc10e 100644 --- a/openbsc/tests/trau/Makefile.am +++ b/openbsc/tests/trau/Makefile.am @@ -1,17 +1,46 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = trau_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = trau_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -trau_test_SOURCES = trau_test.c -trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBRARY_DL) -ldbi +EXTRA_DIST = \ + trau_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + trau_test \ + $(NULL) + +trau_test_SOURCES = \ + trau_test.c \ + $(NULL) + +trau_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..7e33ceb 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -1,21 +1,39 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = xid_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = xid_test +EXTRA_DIST = \ + xid_test.ok \ + $(NULL) -xid_test_SOURCES = xid_test.c +noinst_PROGRAMS = \ + xid_test \ + $(NULL) + +xid_test_SOURCES = \ + xid_test.c \ + $(NULL) xid_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm - + $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp \ + -lrt \ + -lm \ + $(NULL) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer From gerrit-no-reply at lists.osmocom.org Thu Sep 8 23:05:12 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Thu, 8 Sep 2016 23:05:12 +0000 Subject: [PATCH] openbsc[master]: Build fixes Message-ID: Review at https://gerrit.osmocom.org/839 Build fixes Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 --- M openbsc/src/gprs/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 5 files changed, 10 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/839/1 diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 8cb4601..72ccc1c 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -33,6 +33,8 @@ $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOGB_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBGTP_LIBS) \ $(NULL) bin_PROGRAMS = \ @@ -128,5 +130,5 @@ $(LIBOSMOVTY_LIBS) \ $(LIBCARES_LIBS) \ -lrt \ - -lgtp \ + $(LIBGTP_LIBS) \ $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index 654b662..8cf0239 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -7,6 +7,8 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBGTP_CFLAGS) \ $(NULL) EXTRA_DIST = \ @@ -35,6 +37,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 9db9716..0c79737 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -8,6 +8,7 @@ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCRYPTO_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(NULL) noinst_PROGRAMS = \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 46c6089..e5734e6 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -7,6 +7,7 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCARES_CFLAGS) \ $(NULL) @@ -64,7 +65,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 7e33ceb..e269da1 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -32,7 +32,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ -lm \ $(NULL) -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer From gerrit-no-reply at lists.osmocom.org Fri Sep 9 00:05:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 00:05:00 +0000 Subject: [PATCH] libosmocore[master]: fix error msg: msgb_put(): say "msgb_put", not "msgb_push" Message-ID: Review at https://gerrit.osmocom.org/840 fix error msg: msgb_put(): say "msgb_put", not "msgb_push" Change-Id: I72f31ebad693f98eb088a99b83aeb10cf9acc29e --- M include/osmocom/core/msgb.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/40/840/1 diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index b057caa..6f617e2 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -185,7 +185,7 @@ { unsigned char *tmp = msgb->tail; if (msgb_tailroom(msgb) < (int) len) - MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", + MSGB_ABORT(msgb, "Not enough tailroom msgb_put (%u < %u)\n", msgb_tailroom(msgb), len); msgb->tail += len; msgb->len += len; -- To view, visit https://gerrit.osmocom.org/840 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I72f31ebad693f98eb088a99b83aeb10cf9acc29e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 01:48:36 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 01:48:36 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions In-Reply-To: References: Message-ID: Patch Set 1: This failed on the timer test three times now... Are you sure this is not actually breaking the timer test? ;) -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 02:42:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 02:42:15 +0000 Subject: osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Patch Set 1: (2 comments) https://gerrit.osmocom.org/#/c/832/1/src/tbf.cpp File src/tbf.cpp: Line 1253: name(), ws); (technically, you added an indent here) Line 1255: window()->set_ws(ws); After figuring out window() and the 'direction' member, I'm not clear yet: does this function also apply to GPRS_RLCMAC_UL_TBF? It seems correct to use window() to decide for DL, since gprs_rlcmac_tbf is a parent class to gprs_rlcmac_dl_tbf. But are you sure it belongs in the parent class and applies to UL as well? After all, you're using dl_slots() above, which always returns 0 for UL. This makes me think you should rather add this function to gprs_rlcmac_dl_tbf? I see that the other patch modifies gprs_rlcmac_tbf::update(), which would have to do a slightly ugly cast then (or would need to become a virtual function and overloaded in dl). Do you have any insights that clarify this / that justify having this calculation for both DL and UL? -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 9 02:52:26 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 02:52:26 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 1: (6 comments) In general I like these things to be consistent, but I have some bikesheds. https://gerrit.osmocom.org/#/c/838/1/openbsc/Makefile.am File openbsc/Makefile.am: Line 1: AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 $(NULL) Please explain the $(NULL)? This is the first time I'm seeing this. Line 15: pkgconfigdir = $(libdir)/pkgconfig $(NULL) you added a second space after '=' here. Let's have single spaces (or tabs). https://gerrit.osmocom.org/#/c/838/1/openbsc/include/openbsc/Makefile.am File openbsc/include/openbsc/Makefile.am: Line 2: abis_nm.h \ I appreciate that the indenting is now the same on every line, but I was fine with the more compact block, with multiple entries on the same line. https://gerrit.osmocom.org/#/c/838/1/openbsc/src/Makefile.am File openbsc/src/Makefile.am: Line 2: $(all_includes) \ bikeshed ... we could agree to indent all of these with a single tab, regardless of how long the variable name is. That would drop a bunch of spaces-after-tabs. https://gerrit.osmocom.org/#/c/838/1/openbsc/src/gprs/Makefile.am File openbsc/src/gprs/Makefile.am: Line 21: I wouldn't add a blank line here as below is extending AM_CFLAGS. Line 63: I wouldn't separate osmo_gbproxy_* items with a blank line. (same with sgsn etc) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 9 03:11:21 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 03:11:21 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/838/1/openbsc/tests/Makefile.am File openbsc/tests/Makefile.am: Line 77: $(NULL) by adding a $(NULL) here, the executable name './testsuite' gets added a space to become './testsuite ' and thus the test suite cannot run. Hence the jenkins build failure. (One could also remove the single quotes around $(TESTSUITE) below, but since this is not a list that grows and changes I don't see the point of a $(NULL) here.) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:21:08 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:21:08 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-1 I'm all in favor of splitting this up as discussed so far. Also, regarding EGPRS: TS 05.03 predates EGPRS. You need to check it successor 45.003, which should contain all the information regarding channel coding for all GPRS CS and EGPRS MCS in Chapter 7. It would be great to just have the generator polynomials and use generated code for EGPRS, but that could and should be a separate follow-up patch, unrelated to the migration. We might do it before or after. -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:22:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:22:33 +0000 Subject: libosmocore[master]: utils/conv_gen.py: code style changes (line width, tabs, etc.) In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/827 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:23:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:23:36 +0000 Subject: libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 Please be more verbose in the commit message. A single file of what? Which files are now merged into which other file? -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:24:12 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:24:12 +0000 Subject: libosmocore[master]: utils/conv_gen.py: improve output formatting In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 also here, please have at least one sentence indicating how the output formatting is improved. -- To view, visit https://gerrit.osmocom.org/829 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:24:24 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:24:24 +0000 Subject: libosmocore[master]: gsm/gsm0503.h: fix typo In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/830 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I263d61111544eeb7227e1e0e8f2d14479eae2079 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:24:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:24:54 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add RACH, SCH and TCH/AHS definitions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/831 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0ea7151f4e8119a8798a9e129b951559e56b0d93 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:25:11 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:25:11 +0000 Subject: libosmocore[master]: utils/conv_gen.py: fix some typos In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/836 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3327b92715744af4ef61496ef0121555d9d24799 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:28:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:28:47 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions In-Reply-To: References: Message-ID: Patch Set 1: the question to me is, both regarding the existing GSM coding schemes and the new EGPRS MCS: Where are the test cases? We should be able to do a pretty simple Encode -> Decode test to test against our own encoder, and have that test be executed with every of the convolutional codes. We should also be able to introduce a defined amount of bit errors and check if the decoder can still recover as expected (won't work for MCS-9/CS-4, of course). We should also test decoding of some hardcoded 'const uint8_t' arrays of actual messages produced by a different encoder (e.g from air interface traces). -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:29:12 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:29:12 +0000 Subject: libosmocore[master]: fix error msg: msgb_put(): say "msgb_put", not "msgb_push" In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/840 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I72f31ebad693f98eb088a99b83aeb10cf9acc29e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:29:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:29:19 +0000 Subject: [MERGED] libosmocore[master]: fix error msg: msgb_put(): say "msgb_put", not "msgb_push" In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: fix error msg: msgb_put(): say "msgb_put", not "msgb_push" ...................................................................... fix error msg: msgb_put(): say "msgb_put", not "msgb_push" Change-Id: I72f31ebad693f98eb088a99b83aeb10cf9acc29e --- M include/osmocom/core/msgb.h 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index b057caa..6f617e2 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -185,7 +185,7 @@ { unsigned char *tmp = msgb->tail; if (msgb_tailroom(msgb) < (int) len) - MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", + MSGB_ABORT(msgb, "Not enough tailroom msgb_put (%u < %u)\n", msgb_tailroom(msgb), len); msgb->tail += len; msgb->len += len; -- To view, visit https://gerrit.osmocom.org/840 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I72f31ebad693f98eb088a99b83aeb10cf9acc29e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:29:55 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:29:55 +0000 Subject: openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:30:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:30:19 +0000 Subject: libosmocore[master]: fix GGSN Ctrl port to 4257 In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:31:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:31:02 +0000 Subject: libosmocore[master]: comment: */ports.h: hint at wiki page and indicate some used... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 please also point to osmo-gsm-manuals.git to give people an idea that they need to keep this file, the manual and the wiki in sync manually. -- To view, visit https://gerrit.osmocom.org/833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:32:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:32:20 +0000 Subject: osmo-iuh[master]: RAB Assign for voice: heed the x213 nsap flag In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/835 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c3c95d709c8a2b1c48d7a187faca34102226329 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:32:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:32:23 +0000 Subject: [MERGED] osmo-iuh[master]: RAB Assign for voice: heed the x213 nsap flag In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: RAB Assign for voice: heed the x213 nsap flag ...................................................................... RAB Assign for voice: heed the x213 nsap flag Add use_x213_nsap arg to ranap_new_msg_rab_assign_voice() and new_transp_info_rtp(). Pass this to new_transp_layer_addr() to compose 32bit addresses when use_x213_nsap == false. This is analogous to ranap_new_msg_rab_assign_data(). Particularly, the ip.access nano3G does not accept x213 NSAP 56bit addresses, so we want to send 32bit addresses there. Change-Id: I0c3c95d709c8a2b1c48d7a187faca34102226329 --- M include/osmocom/ranap/ranap_msg_factory.h M src/ranap_msg_factory.c M src/tests/test-ranap.c 3 files changed, 12 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ranap/ranap_msg_factory.h b/include/osmocom/ranap/ranap_msg_factory.h index 9639881..120c6e6 100644 --- a/include/osmocom/ranap/ranap_msg_factory.h +++ b/include/osmocom/ranap/ranap_msg_factory.h @@ -32,7 +32,9 @@ struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause); /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ -struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port); +struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, + uint16_t rtp_port, + bool use_x213_nsap); /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data) */ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 401ef4e..695a6be 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -647,7 +647,8 @@ out->bits_unused = 0; } -static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port) +static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port, + bool use_x213_nsap) { RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); uint8_t binding_id[4]; @@ -661,7 +662,7 @@ binding_id[3] = 1; #endif - new_transp_layer_addr(&tli->transportLayerAddress, ip, 1); + new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID, (const char *) binding_id, sizeof(binding_id)); @@ -710,7 +711,9 @@ } /*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ -struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port) +struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, + uint16_t rtp_port, + bool use_x213_nsap) { RANAP_ProtocolIE_FieldPair_t *pair; RANAP_RAB_AssignmentRequestIEs_t ies; @@ -731,7 +734,8 @@ //first.nAS_SynchronisationIndicator = FIXME; first.rAB_Parameters = new_rab_par_voice(); first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */ - first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port); + first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port, + use_x213_nsap); /* put together the 'Second' part */ RANAP_RAB_SetupOrModifyItemSecond_t second; diff --git a/src/tests/test-ranap.c b/src/tests/test-ranap.c index 7b1f3bf..ce01b96 100644 --- a/src/tests/test-ranap.c +++ b/src/tests/test-ranap.c @@ -148,7 +148,7 @@ msgb_free(msg); printf("\n==> RAB ASSIGNMENT COMMAND (VOICE)\n"); - msg = ranap_new_msg_rab_assign_voice(1, rtp_ip, rtp_port); + msg = ranap_new_msg_rab_assign_voice(1, rtp_ip, rtp_port, 1); if (msg) printf("%s\n", msgb_hexdump(msg)); msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/835 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0c3c95d709c8a2b1c48d7a187faca34102226329 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:32:51 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 06:32:51 +0000 Subject: libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Patch Set 1: > Please be more verbose in the commit message. A single file of > what? Which files are now merged into which other file? No problem, I will extend the commit message. -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:33:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:33:27 +0000 Subject: osmo-bts[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 1: > Ok, we could say "telnet at 127.0.0.1 4245" ... yes, let's just do that. also, the control interface port should be reported by the library, not each application. -- To view, visit https://gerrit.osmocom.org/754 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:34:21 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:34:21 +0000 Subject: osmo-iuh[master]: UE Register with TMSI: reply with a Register Reject In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/723 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia47e398e50e316842cd260dc0d9a4e2d8a1c627c Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:34:24 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:34:24 +0000 Subject: [MERGED] osmo-iuh[master]: UE Register with TMSI: reply with a Register Reject In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: UE Register with TMSI: reply with a Register Reject ...................................................................... UE Register with TMSI: reply with a Register Reject When receiving a UE Register Request with TMSI and no IMSI, compose a Register Reject with the same UE Identity and send. The accepting function expects a ue_context argument and composes the message from the IMSI found there. This new rejection message cannot rely on a ue_context struct and hence uses the asn1 uE_Identity directly. Change-Id: Ia47e398e50e316842cd260dc0d9a4e2d8a1c627c --- M src/hnbgw_hnbap.c 1 file changed, 65 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 8a0bc9b..5246b81 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -114,6 +114,69 @@ return hnbgw_hnbap_tx(ue->hnb, msg); } +static int hnbgw_tx_ue_register_rej_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id) +{ + UERegisterReject_t reject_out; + UERegisterRejectIEs_t reject; + struct msgb *msg; + int rc; + + memset(&reject, 0, sizeof(reject)); + reject.uE_Identity.present = ue_id->present; + + if (ue_id->present != UE_Identity_PR_tMSILAI) { + LOGP(DHNBAP, LOGL_ERROR, "Trying to reject UE Register without IMSI: only rejects of UE_Identity_PR_tMSILAI supported so far.\n"); + return -1; + } + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", + ue_id->choice.tMSILAI.tMSI.size, + osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.tMSILAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.tMSILAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size)); + + BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + + reject.cause.present = Cause_PR_radioNetwork; + reject.cause.choice.radioNetwork = CauseRadioNetwork_invalid_UE_identity; + + memset(&reject_out, 0, sizeof(reject_out)); + rc = hnbap_encode_ueregisterrejecties(&reject_out, &reject); + if (rc < 0) { + return rc; + } + + msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister, + Criticality_reject, + &asn_DEF_UERegisterReject, + &reject_out); + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, &reject.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out); + + return hnbgw_hnbap_tx(hnb, msg); +} + static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in) { HNBDe_RegisterIEs_t ies; @@ -187,8 +250,9 @@ LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n"); /* TODO: this is probably a TMSI registration. Store TMSIs * and look them up to accept UE Registration. */ + rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); hnbap_free_ueregisterrequesties(&ies); - return -1; + return rc; } DEBUGP(DHNBAP, "UE-REGISTER-REQ ID_type=%d imsi=%s cause=%ld\n", -- To view, visit https://gerrit.osmocom.org/723 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia47e398e50e316842cd260dc0d9a4e2d8a1c627c Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:34:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:34:54 +0000 Subject: [MERGED] libosmo-abis[master]: Change API to convey marker bit In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Change API to convey marker bit ...................................................................... Change API to convey marker bit Previously RTP receive callback ignored Marker bit from RTP headers. Extend API to include it explicitly. Change-Id: I3c2b6365d8a51bf98805614e07344d2639875fde Related: OS#1750 --- M TODO-RELEASE M include/osmocom/trau/osmo_ortp.h M src/trau/osmo_ortp.c 3 files changed, 6 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/TODO-RELEASE b/TODO-RELEASE index 43b1e8e..7ea65b6 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -1 +1,2 @@ #library what description / commit summary line +libosmo-abis API change major: add parameter to rx_cb() callack in osmo_ortp.h diff --git a/include/osmocom/trau/osmo_ortp.h b/include/osmocom/trau/osmo_ortp.h index 7c2a5cb..1c0b223 100644 --- a/include/osmocom/trau/osmo_ortp.h +++ b/include/osmocom/trau/osmo_ortp.h @@ -55,7 +55,7 @@ /*! \brief callback for incoming data */ void (*rx_cb)(struct osmo_rtp_socket *rs, const uint8_t *payload, - unsigned int payload_len); + unsigned int payload_len, bool marker); /*! \brief Receive user timestamp, to be incremented by user */ uint32_t rx_user_ts; diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index cdcc1e7..cc1d748 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -159,7 +159,8 @@ /* hand into receiver */ if (rs->rx_cb) rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr); + mblk->b_wptr - mblk->b_rptr, + rtp_get_markbit(mblk)); //rs->rx_user_ts += 160; freemsg(mblk); return 1; @@ -189,7 +190,8 @@ /* hand into receiver */ if (rs->rx_cb) rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr); + mblk->b_wptr - mblk->b_rptr, + rtp_get_markbit(mblk)); freemsg(mblk); } else LOGP(DLMIB, LOGL_INFO, "recvm_with_ts(%u): ERROR!\n", -- To view, visit https://gerrit.osmocom.org/688 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3c2b6365d8a51bf98805614e07344d2639875fde Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:35:18 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:35:18 +0000 Subject: libosmocore[master]: libosmocodec link fix on MacOSX In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/802 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id7358b94e274b529a8da38a0b2ef8c892b6dd7a5 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:35:21 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:35:21 +0000 Subject: [MERGED] libosmocore[master]: libosmocodec link fix on MacOSX In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: libosmocodec link fix on MacOSX ...................................................................... libosmocodec link fix on MacOSX Fixes the following bug: CCLD libosmocodec.la Undefined symbols for architecture x86_64: "_bitvec_get_bit_pos", referenced from: _osmo_fr_check_sid in gsm610.o "_bitvec_get_uint", referenced from: _osmo_hr_check_sid in gsm620.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [libosmocodec.la] Error 1 Change-Id: Id7358b94e274b529a8da38a0b2ef8c892b6dd7a5 --- M src/codec/Makefile.am 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/codec/Makefile.am b/src/codec/Makefile.am index 619897f..5c69c28 100644 --- a/src/codec/Makefile.am +++ b/src/codec/Makefile.am @@ -9,3 +9,4 @@ libosmocodec_la_SOURCES = gsm610.c gsm620.c gsm660.c gsm690.c libosmocodec_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined +libosmocodec_la_LIBADD = $(top_builddir)/src/libosmocore.la -- To view, visit https://gerrit.osmocom.org/802 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id7358b94e274b529a8da38a0b2ef8c892b6dd7a5 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:35:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:35:42 +0000 Subject: [MERGED] libosmocore[master]: Add Marker to ph_tch_param In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add Marker to ph_tch_param ...................................................................... Add Marker to ph_tch_param Extend struct ph_tch_param with Marker bit from RTP header to indicate speech onset in case of DTX. Change-Id: Ic664902630b9d335ff9abc7a9ca7249eaf80e05f Related: OS#1750 --- M TODO-RELEASE M include/osmocom/gsm/l1sap.h 2 files changed, 3 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/TODO-RELEASE b/TODO-RELEASE index 472b328..648b6a6 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -2,4 +2,5 @@ libosmogsm internal API update Internal API for GPRS cipher implementors updated to accommodate for arbitrary key lengths libosmocore change major external talloc dependency / internal talloc removal libosmocore change major size of ph_data_param struct changed / Extend L1SAP PH-DATA with presence information -libosmocore change major size of ph_data_param struct changed / Extend L1SAP PH-DATA with measurement information \ No newline at end of file +libosmocore change major size of ph_data_param struct changed / Extend L1SAP PH-DATA with measurement information +libosmocore change major size of ph_tch_param struct changed / Extend with RTP Marker diff --git a/include/osmocom/gsm/l1sap.h b/include/osmocom/gsm/l1sap.h index f0e9f6c..e199efe 100644 --- a/include/osmocom/gsm/l1sap.h +++ b/include/osmocom/gsm/l1sap.h @@ -81,6 +81,7 @@ uint8_t chan_nr; /*!< \brief Channel Number (Like RSL) */ uint32_t fn; /*!< \brief GSM Frame Number */ int8_t rssi; /*!< \brief RSSI of received indication */ + uint8_t marker; /*!< \brief RTP Marker bit (speech onset indicator) */ }; /*! \brief for PH-CONN.ind */ -- To view, visit https://gerrit.osmocom.org/690 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic664902630b9d335ff9abc7a9ca7249eaf80e05f Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:36:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:36:58 +0000 Subject: osmo-pcu[master]: Fix Timing Advance handling In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/547 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idfc40ff0c11bdac13d9e28fbfa4e95dfc6b735b0 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:37:05 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:37:05 +0000 Subject: [MERGED] osmo-pcu[master]: Fix Timing Advance handling In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Fix Timing Advance handling ...................................................................... Fix Timing Advance handling * initialize with invalid TA instead of making assumption that phone is located within 550 meters (TA=0) * only set valid TA Change-Id: Idfc40ff0c11bdac13d9e28fbfa4e95dfc6b735b0 Related: OS#1526 --- M src/bts.cpp M src/gprs_ms.cpp M src/sba.cpp M src/tbf.cpp M src/tbf_dl.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 7 files changed, 121 insertions(+), 86 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/bts.cpp b/src/bts.cpp index e65d608..795baa6 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -33,6 +33,7 @@ #include #include #include + #include } #include @@ -1129,7 +1130,7 @@ uint32_t tlli = request->ID.u.TLLI; uint8_t ms_class = 0; uint8_t egprs_ms_class = 0; - uint8_t ta = 0; + uint8_t ta = GSM48_TA_INVALID; struct pcu_l1_meas meas; GprsMs *ms = bts()->ms_by_tlli(tlli); diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index b3270b1..8facc50 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -32,6 +32,7 @@ extern "C" { #include #include + #include } #define GPRS_CODEL_SLOW_INTERVAL_MS 4000 @@ -95,7 +96,7 @@ m_tlli(tlli), m_new_ul_tlli(0), m_new_dl_tlli(0), - m_ta(0), + m_ta(GSM48_TA_INVALID), m_ms_class(0), m_egprs_ms_class(0), m_is_idle(true), @@ -464,11 +465,15 @@ if (ta_ == m_ta) return; - LOGP(DRLCMAC, LOGL_INFO, - "Modifying MS object, TLLI = 0x%08x, TA %d -> %d\n", - tlli(), m_ta, ta_); - - m_ta = ta_; + if (gsm48_ta_is_valid(ta_)) { + LOGP(DRLCMAC, LOGL_INFO, + "Modifying MS object, TLLI = 0x%08x, TA %d -> %d\n", + tlli(), m_ta, ta_); + m_ta = ta_; + } else + LOGP(DRLCMAC, LOGL_NOTICE, + "MS object, TLLI = 0x%08x, invalid TA %d rejected (old " + "value %d kept)\n", tlli(), ta_, m_ta); } void GprsMs::set_ms_class(uint8_t ms_class_) diff --git a/src/sba.cpp b/src/sba.cpp index 6aeeb7c..46c1431 100644 --- a/src/sba.cpp +++ b/src/sba.cpp @@ -26,6 +26,7 @@ extern "C" { #include +#include } #include @@ -55,6 +56,9 @@ if (!sba) return -ENOMEM; + if (!gsm48_ta_is_valid(ta)) + return -EINVAL; + for (trx = 0; trx < 8; trx++) { for (ts = 7; ts >= 0; ts--) { pdch = &m_bts.bts_data()->trx[trx].pdch[ts]; diff --git a/src/tbf.cpp b/src/tbf.cpp index 1fc1aef..7a15547 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -74,7 +74,7 @@ m_tfi(0), m_created_ts(0), m_ms(NULL), - m_ta(0), + m_ta(GSM48_TA_INVALID), m_ms_class(0), m_list(this), m_ms_list(this), @@ -151,7 +151,8 @@ if (ms()) ms()->set_ta(ta); - m_ta = ta; + if (gsm48_ta_is_valid(ta)) + m_ta = ta; } uint8_t gprs_rlcmac_tbf::ms_class() const diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 4c67a12..489020b 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -120,7 +120,7 @@ { uint8_t ss; int8_t use_trx; - uint16_t ta = 0; + uint16_t ta = GSM48_TA_INVALID; struct gprs_rlcmac_ul_tbf *ul_tbf = NULL, *old_ul_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; GprsMs *ms; diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..cdf8ff4 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -181,6 +181,7 @@ tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1); + dl_tbf->set_ta(0); check_tbf(dl_tbf); /* "Establish" the DL TBF */ @@ -505,6 +506,7 @@ ms = the_bts.ms_store().get_ms(0, 0, imsi); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms->dl_tbf() != NULL); + ms->dl_tbf()->set_ta(0); /* Handle LLC frame 2 */ memset(buf, 2, sizeof(buf)); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..a905b1b 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -15,7 +15,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 04, dl_slots = 04 The MS object cannot fully confirm an unexpected TLLI: 0x00002342, partly confirmed -Modifying MS object, TLLI = 0x00002342, TA 0 -> 4 +Modifying MS object, TLLI = 0x00002342, TA 220 -> 4 ********** TBF starts here ********** Allocating UL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 @@ -54,6 +54,7 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append @@ -141,6 +142,7 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append @@ -228,6 +230,7 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append @@ -530,6 +533,7 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW Searching for first unallocated TFI: TRX=0 Found TFI=1. @@ -550,6 +554,7 @@ - Setting Control TS 4 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 10 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xf1000001, partly confirmed The MS object cannot fully confirm an unexpected TLLI: 0xf1000002, partly confirmed @@ -595,8 +600,8 @@ Send dowlink assignment for TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000000) TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 08 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -622,8 +627,8 @@ Send dowlink assignment for TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000001) TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 18 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 23 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -649,8 +654,8 @@ Send dowlink assignment for TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000002) TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 28 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 23 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -676,8 +681,8 @@ Send dowlink assignment for TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000003) TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -703,8 +708,8 @@ Send dowlink assignment for TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000004) TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 49 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 23 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -730,8 +735,8 @@ Send dowlink assignment for TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000005) TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 59 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 23 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -757,8 +762,8 @@ Send dowlink assignment for TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000006) TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 69 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 23 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -784,8 +789,8 @@ Send dowlink assignment for TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000007) TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -811,8 +816,8 @@ Send dowlink assignment for TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000008) TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -838,8 +843,8 @@ Send dowlink assignment for TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000009) TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -865,8 +870,8 @@ Send dowlink assignment for TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000010) TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -892,8 +897,8 @@ Send dowlink assignment for TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000011) TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -919,8 +924,8 @@ Send dowlink assignment for TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000012) TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -946,8 +951,8 @@ Send dowlink assignment for TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000013) TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 db 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 23 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -973,8 +978,8 @@ Send dowlink assignment for TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000014) TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1000,8 +1005,8 @@ Send dowlink assignment for TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000015) TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1027,8 +1032,8 @@ Send dowlink assignment for TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000016) TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1054,8 +1059,8 @@ Send dowlink assignment for TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000017) TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1081,8 +1086,8 @@ Send dowlink assignment for TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000018) TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1108,8 +1113,8 @@ Send dowlink assignment for TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000019) TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1135,8 +1140,8 @@ Send dowlink assignment for TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000020) TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1162,8 +1167,8 @@ Send dowlink assignment for TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000021) TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1189,8 +1194,8 @@ Send dowlink assignment for TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000022) TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1216,8 +1221,8 @@ Send dowlink assignment for TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000023) TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1243,8 +1248,8 @@ Send dowlink assignment for TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000024) TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1270,8 +1275,8 @@ Send dowlink assignment for TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000025) TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1297,8 +1302,8 @@ Send dowlink assignment for TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000026) TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1324,8 +1329,8 @@ Send dowlink assignment for TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000027) TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 be c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 23 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1351,8 +1356,8 @@ Send dowlink assignment for TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000028) TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1378,8 +1383,8 @@ Send dowlink assignment for TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000029) TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 df 40 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 23 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1405,8 +1410,8 @@ Send dowlink assignment for TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000030) TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1432,8 +1437,8 @@ Send dowlink assignment for TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000031) TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1467,10 +1472,11 @@ Send dowlink assignment for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000123456) TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - - TRX=0 (0) TS=4 TA=0 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b + - TRX=0 (0) TS=4 TA=220 pollFN=-1 +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append +Modifying MS object, TLLI = 0xc0123456, TA 220 -> 0 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to RELEASING TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) free @@ -1555,7 +1561,7 @@ - Setting Control TS 7 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL): trx = 0, ul_slots = 80, dl_slots = 00 -Modifying MS object, TLLI = 0x00000000, TA 0 -> 7 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 7 TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to FLOW TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) starting timer 3169. TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) [UPLINK] START @@ -1642,7 +1648,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ @@ -1728,7 +1734,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ @@ -1868,7 +1874,7 @@ TBF(TFI=1 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=1 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf5667788, not yet confirmed -Modifying MS object, TLLI = 0xf5667788, TA 0 -> 7 +Modifying MS object, TLLI = 0xf5667788, TA 220 -> 7 Change control TS to 7 until assinment is complete. Received RTS for PDCH: TRX=0 TS=7 FN=2654335 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) @@ -1941,7 +1947,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ @@ -2120,7 +2126,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ @@ -2200,7 +2206,7 @@ - Setting Control TS 7 Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL): trx = 0, ul_slots = 80, dl_slots = 00 -Modifying MS object, TLLI = 0x00000000, TA 0 -> 7 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 7 TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to FLOW TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) starting timer 3169. TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) [UPLINK] START @@ -2272,7 +2278,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ @@ -3412,7 +3418,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) @@ -3747,6 +3753,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4080,6 +4087,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4358,6 +4366,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4595,6 +4604,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4796,6 +4806,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -4975,6 +4986,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5135,6 +5147,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5291,6 +5304,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5434,6 +5448,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5578,6 +5593,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5628,6 +5644,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5678,6 +5695,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5728,6 +5746,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5797,6 +5816,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5866,6 +5886,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -5935,6 +5956,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append -- To view, visit https://gerrit.osmocom.org/547 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idfc40ff0c11bdac13d9e28fbfa4e95dfc6b735b0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:39:32 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:39:32 +0000 Subject: osmo-iuh[master]: jenkins.sh: don't build twice In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/776 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18e7677d8596f61b883e9db57b4bdd2a5c154ec3 Gerrit-PatchSet: 6 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:40:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:40:02 +0000 Subject: osmo-iuh[master]: tests: don't log filename nor color in unit tests In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/779 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie76384c4176ce0a7d89d093f2efb848fe3f19400 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:40:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:40:28 +0000 Subject: osmo-iuh[master]: build: use tar-ustar to allow paths longer than 99 In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/780 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id41bca92810a81ac50697c0230a6caef490b0ffd Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:40:40 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:40:40 +0000 Subject: osmo-iuh[master]: build: remove subdir-objects from configure.ac, it is broken In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/781 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia47b038d4ca4f6c345711fb17d074f71c80e4453 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:41:40 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:41:40 +0000 Subject: osmo-iuh[master]: build: fix ranap gen, use same for gen hnbap and rua gen In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/782 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I32213666fcdfc144008fa7d46497c0938d093e86 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:42:21 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:42:21 +0000 Subject: osmo-iuh[master]: build: distcheck: add missing distclean files In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/783 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I24d72b2b1bae52a1b2cf8a989396d2aac31d119e Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:42:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:42:34 +0000 Subject: osmo-iuh[master]: build: distcheck: look for asn1 in top_srcdir, not top_builddir In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/784 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iebcff240ba2fae964dad2a2c481fcbfd29e14e69 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:42:48 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:42:48 +0000 Subject: osmo-iuh[master]: build: distcheck: add missing bits for testsuite distcheck In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/785 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I13d76cd56dfb8fe4eb02d6fcada78a9e3311b51b Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:03 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:03 +0000 Subject: osmo-iuh[master]: build: cosmetic: hnbap: undup asn1 src path In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/786 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0507277995302261c87db1b0c48105065cf13ae4 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:15 +0000 Subject: osmo-iuh[master]: build: move headers to include/osmocom/* In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/787 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5a82e029dcdc4df0a60a31271a4883393fe59234 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:22 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:22 +0000 Subject: osmo-iuh[master]: build: parallel build: require ../libosmo-ranap.la from tests/ In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/788 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8107e08e4c211f20d671f520bf6bab9356f3c90e Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:27 +0000 Subject: osmo-iuh[master]: jenkins.sh: enable make distcheck In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/789 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I967d4de9682cb2a45210f689ec076ef457841179 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: jenkins.sh: enable make distcheck In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: jenkins.sh: enable make distcheck ...................................................................... jenkins.sh: enable make distcheck Change-Id: I967d4de9682cb2a45210f689ec076ef457841179 --- M contrib/jenkins.sh 1 file changed, 1 insertion(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 72efdbc..8021bbd 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -75,5 +75,4 @@ $MAKE $PARALLEL_MAKE LD_LIBRARY_PATH="$inst/lib" $MAKE check -# distcheck is broken -#LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck +LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/789 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I967d4de9682cb2a45210f689ec076ef457841179 Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: build: parallel build: require ../libosmo-ranap.la from tests/ In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: parallel build: require ../libosmo-ranap.la from tests/ ...................................................................... build: parallel build: require ../libosmo-ranap.la from tests/ This rule is bad because it re-invokes $(MAKE), but it seems to fix the parallel build. It should probably be done differently. Change-Id: I8107e08e4c211f20d671f520bf6bab9356f3c90e --- M src/tests/Makefile.am 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 3a99681..5b51262 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -27,6 +27,9 @@ dummy_cn_SOURCES = $(RANAP_FILES) test_common.c dummy_cn_sua.c dummy_cn_LDADD = $(COMMON_LIBS) $(top_builddir)/src/libosmo-ranap.la +$(top_builddir)/src/libosmo-ranap.la: + $(MAKE) -C $(top_builddir)/src libosmo-ranap.la + # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac :;{ \ -- To view, visit https://gerrit.osmocom.org/788 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8107e08e4c211f20d671f520bf6bab9356f3c90e Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: build: move headers to include/osmocom/* In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: move headers to include/osmocom/* ...................................................................... build: move headers to include/osmocom/* This came up while fixing 'make distcheck'; this is certainly not the easiest way but it makes sense to have the headers in include/, like we do in openbsc. The easy alternative might be to add -I$(top_srcdir)/src to src/Makefile.am. Remove -I$(top_srcdir)/src from src/tests/Makefile.am, no longer needed. Change-Id: I5a82e029dcdc4df0a60a31271a4883393fe59234 --- M include/osmocom/iuh/Makefile.am R include/osmocom/iuh/context_map.h R include/osmocom/iuh/hnbgw.h R include/osmocom/iuh/hnbgw_cn.h R include/osmocom/iuh/hnbgw_hnbap.h R include/osmocom/iuh/hnbgw_ranap.h R include/osmocom/iuh/hnbgw_rua.h R include/osmocom/iuh/iu_common.h M include/osmocom/rua/Makefile.am R include/osmocom/rua/rua_msg_factory.h M src/Makefile.am M src/context_map.c M src/hnbap_common.c M src/hnbgw.c M src/hnbgw_cn.c M src/hnbgw_hnbap.c M src/hnbgw_ranap.c M src/hnbgw_rua.c M src/hnbgw_vty.c M src/ranap_common_cn.c M src/rua_common.c M src/rua_msg_factory.c M src/tests/Makefile.am M src/tests/dummy_cn_sua.c M src/tests/hnb-test.c M src/tests/test-ranap.c M src/tests/test_common.c 27 files changed, 41 insertions(+), 37 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/iuh/Makefile.am b/include/osmocom/iuh/Makefile.am index e2f7126..b2a667d 100644 --- a/include/osmocom/iuh/Makefile.am +++ b/include/osmocom/iuh/Makefile.am @@ -1,2 +1,4 @@ noinst_HEADERS = \ - vty.h + vty.h \ + context_map.h hnbgw.h hnbgw_cn.h \ + hnbgw_hnbap.h hnbgw_rua.h hnbgw_ranap.h diff --git a/src/context_map.h b/include/osmocom/iuh/context_map.h similarity index 100% rename from src/context_map.h rename to include/osmocom/iuh/context_map.h diff --git a/src/hnbgw.h b/include/osmocom/iuh/hnbgw.h similarity index 100% rename from src/hnbgw.h rename to include/osmocom/iuh/hnbgw.h diff --git a/src/hnbgw_cn.h b/include/osmocom/iuh/hnbgw_cn.h similarity index 78% rename from src/hnbgw_cn.h rename to include/osmocom/iuh/hnbgw_cn.h index 469b3d4..d5bec04 100644 --- a/src/hnbgw_cn.h +++ b/include/osmocom/iuh/hnbgw_cn.h @@ -1,5 +1,5 @@ #pragma once -#include "hnbgw.h" +#include struct hnbgw_cnlink *hnbgw_cnlink_init(struct hnb_gw *gw, const char *host, uint16_t port, int is_ps); diff --git a/src/hnbgw_hnbap.h b/include/osmocom/iuh/hnbgw_hnbap.h similarity index 77% rename from src/hnbgw_hnbap.h rename to include/osmocom/iuh/hnbgw_hnbap.h index 955e0aa..cca3550 100644 --- a/src/hnbgw_hnbap.h +++ b/include/osmocom/iuh/hnbgw_hnbap.h @@ -1,6 +1,6 @@ #pragma once -#include "hnbgw.h" +#include int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg); int hnbgw_hnbap_init(void); diff --git a/src/hnbgw_ranap.h b/include/osmocom/iuh/hnbgw_ranap.h similarity index 77% rename from src/hnbgw_ranap.h rename to include/osmocom/iuh/hnbgw_ranap.h index 85a2f98..2c55964 100644 --- a/src/hnbgw_ranap.h +++ b/include/osmocom/iuh/hnbgw_ranap.h @@ -1,6 +1,6 @@ #pragma once -#include "hnbgw.h" +#include int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len); int hnbgw_ranap_init(void); diff --git a/src/hnbgw_rua.h b/include/osmocom/iuh/hnbgw_rua.h similarity index 93% rename from src/hnbgw_rua.h rename to include/osmocom/iuh/hnbgw_rua.h index d170190..6a890b7 100644 --- a/src/hnbgw_rua.h +++ b/include/osmocom/iuh/hnbgw_rua.h @@ -1,6 +1,6 @@ #pragma once -#include "hnbgw.h" +#include #include int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg); diff --git a/src/iu_common.h b/include/osmocom/iuh/iu_common.h similarity index 100% rename from src/iu_common.h rename to include/osmocom/iuh/iu_common.h diff --git a/include/osmocom/rua/Makefile.am b/include/osmocom/rua/Makefile.am index 49e2150..307f123 100644 --- a/include/osmocom/rua/Makefile.am +++ b/include/osmocom/rua/Makefile.am @@ -1,5 +1,5 @@ noinst_HEADERS = \ - rua_common.h rua_ies_defs.h \ + rua_common.h rua_ies_defs.h rua_msg_factory.h \ RUA_Ansi-41-IDNNS.h \ RUA_Cause.h \ RUA_CauseMisc.h \ diff --git a/src/rua_msg_factory.h b/include/osmocom/rua/rua_msg_factory.h similarity index 100% rename from src/rua_msg_factory.h rename to include/osmocom/rua/rua_msg_factory.h diff --git a/src/Makefile.am b/src/Makefile.am index 2779315..bb1ebbd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,9 +60,6 @@ # bin_PROGRAMS = osmo-hnbgw -noinst_HEADERS = context_map.h hnbgw.h hnbgw_cn.h \ - hnbgw_hnbap.h hnbgw_rua.h hnbgw_ranap.h - osmo_hnbgw_SOURCES = hnbap_encoder.c hnbap_decoder.c hnbap_common.c \ rua_encoder.c rua_decoder.c rua_common.c \ rua_msg_factory.c \ diff --git a/src/context_map.c b/src/context_map.c index 22eb605..052133c 100644 --- a/src/context_map.c +++ b/src/context_map.c @@ -24,8 +24,8 @@ #include -#include "hnbgw.h" -#include "context_map.h" +#include +#include /* is a given SCCP USER SAP Connection ID in use for a given CN link? */ static int cn_id_in_use(struct hnbgw_cnlink *cn, uint32_t id) diff --git a/src/hnbap_common.c b/src/hnbap_common.c index 2cd6519..f8cfb13 100644 --- a/src/hnbap_common.c +++ b/src/hnbap_common.c @@ -25,7 +25,7 @@ #include #include -#include "hnbgw.h" +#include static const struct value_string hnbap_cause_radio_vals[] = { { CauseRadioNetwork_overload, "overload" }, diff --git a/src/hnbgw.c b/src/hnbgw.c index 4f23e8d..d50e622 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -51,11 +51,11 @@ #include #include -#include "hnbgw.h" -#include "hnbgw_hnbap.h" -#include "hnbgw_rua.h" -#include "hnbgw_cn.h" -#include "context_map.h" +#include +#include +#include +#include +#include static const char * const osmo_hnbgw_copyright = "OsmoHNBGW - Osmocom Home Node B Gateway implementation\r\n" diff --git a/src/hnbgw_cn.c b/src/hnbgw_cn.c index 09b2726..e41788d 100644 --- a/src/hnbgw_cn.c +++ b/src/hnbgw_cn.c @@ -29,11 +29,11 @@ #include #include -#include "hnbgw.h" -#include "hnbgw_rua.h" +#include +#include #include #include -#include "context_map.h" +#include /*********************************************************************** * Outbound RANAP RESET to CN diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index c329fe4..7bf54c8 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -31,7 +31,7 @@ #include #include -#include "hnbgw.h" +#include #include #define IU_MSG_NUM_IES 32 diff --git a/src/hnbgw_ranap.c b/src/hnbgw_ranap.c index dde1183..7a505a5 100644 --- a/src/hnbgw_ranap.c +++ b/src/hnbgw_ranap.c @@ -29,8 +29,8 @@ #include "asn1helpers.h" -#include "hnbgw.h" -#include "hnbgw_rua.h" +#include +#include #include #include #include diff --git a/src/hnbgw_rua.c b/src/hnbgw_rua.c index fc22bfc..3f245b5 100644 --- a/src/hnbgw_rua.c +++ b/src/hnbgw_rua.c @@ -32,11 +32,11 @@ #include "asn1helpers.h" -#include "hnbgw.h" -#include "hnbgw_ranap.h" +#include +#include #include #include -#include "context_map.h" +#include static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg) { diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index 1673c0c..2e3d1e9 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -22,8 +22,8 @@ #include -#include "hnbgw.h" -#include "context_map.h" +#include +#include static void *tall_hnb_ctx = NULL; static struct hnb_gw *g_hnb_gw = NULL; diff --git a/src/ranap_common_cn.c b/src/ranap_common_cn.c index 2c80dd0..3736dce 100644 --- a/src/ranap_common_cn.c +++ b/src/ranap_common_cn.c @@ -29,7 +29,7 @@ #include #include -#include "hnbgw.h" +#include static int cn_ranap_rx_initiating_msg_co(void *ctx, RANAP_InitiatingMessage_t *imsg, ranap_message *message) diff --git a/src/rua_common.c b/src/rua_common.c index a5ab044..3c9d773 100644 --- a/src/rua_common.c +++ b/src/rua_common.c @@ -24,7 +24,7 @@ #include #include -#include "hnbgw.h" +#include extern int asn1_xer_print; diff --git a/src/rua_msg_factory.c b/src/rua_msg_factory.c index 0bce326..268f6ac 100644 --- a/src/rua_msg_factory.c +++ b/src/rua_msg_factory.c @@ -3,9 +3,9 @@ #include #include -#include "rua_msg_factory.h" +#include #include "asn1helpers.h" -#include "hnbgw.h" +#include struct msgb *rua_new_udt(struct msgb *inmsg) diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 2ba3e89..3a99681 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -1,9 +1,14 @@ -AM_CFLAGS = -g -I$(top_srcdir)/src -I$(top_srcdir)/include $(OSMOVTY_CFLAGS) $(OSMOCORE_CFLAGS) $(OSMOGSM_CFLAGS) $(OSMONETIF_CFLAGS) $(ASN1C_CFLAGS) $(OSMOSIGTRAN_CFLAGS) +AM_CFLAGS = -g -I$(top_srcdir)/src/tests \ + -I$(top_srcdir)/include -I$(top_builddir)/include \ + $(OSMOVTY_CFLAGS) $(OSMOCORE_CFLAGS) $(OSMOGSM_CFLAGS) \ + $(OSMONETIF_CFLAGS) $(ASN1C_CFLAGS) $(OSMOSIGTRAN_CFLAGS) COMMON_LIBS = $(OSMOVTY_LIBS) $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(ASN1C_LIBS) $(OSMOSIGTRAN_LIBS) -lsctp check_PROGRAMS = test-ranap test-helpers test-hnbap hnb-test dummy-cn +noinst_HEADERS = test_common.h hnb-test.h hnb-test-layers.h + HNBAP_FILES = $(top_srcdir)/src/hnbap_common.c $(top_srcdir)/src/hnbap_decoder.c $(top_srcdir)/src/hnbap_encoder.c RUA_FILES = $(top_srcdir)/src/rua_common.c $(top_srcdir)/src/rua_decoder.c $(top_srcdir)/src/rua_encoder.c $(top_srcdir)/src/rua_msg_factory.c diff --git a/src/tests/dummy_cn_sua.c b/src/tests/dummy_cn_sua.c index c2fc712..f9b4244 100644 --- a/src/tests/dummy_cn_sua.c +++ b/src/tests/dummy_cn_sua.c @@ -24,7 +24,7 @@ #include #include #include -#include "hnbgw.h" +#include int asn1_xer_print = 1; const char *cmdline_bind_addr = "127.0.0.1"; diff --git a/src/tests/hnb-test.c b/src/tests/hnb-test.c index 2c41199..d338077 100644 --- a/src/tests/hnb-test.c +++ b/src/tests/hnb-test.c @@ -54,7 +54,7 @@ #include "hnb-test-layers.h" #include #include -#include "rua_msg_factory.h" +#include #include "asn1helpers.h" #include #include "test_common.h" diff --git a/src/tests/test-ranap.c b/src/tests/test-ranap.c index ce01b96..c70009b 100644 --- a/src/tests/test-ranap.c +++ b/src/tests/test-ranap.c @@ -32,7 +32,7 @@ #include "test_common.h" -#include "hnbgw.h" +#include int asn1_xer_print = 1; diff --git a/src/tests/test_common.c b/src/tests/test_common.c index a79d5f5..5a37e7e 100644 --- a/src/tests/test_common.c +++ b/src/tests/test_common.c @@ -37,7 +37,7 @@ #include #include -#include "hnbgw.h" +#include void *talloc_asn1_ctx; -- To view, visit https://gerrit.osmocom.org/787 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5a82e029dcdc4df0a60a31271a4883393fe59234 Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: build: cosmetic: hnbap: undup asn1 src path In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: cosmetic: hnbap: undup asn1 src path ...................................................................... build: cosmetic: hnbap: undup asn1 src path Change-Id: I0507277995302261c87db1b0c48105065cf13ae4 --- M src/hnbap/Makefile.am 1 file changed, 3 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbap/Makefile.am b/src/hnbap/Makefile.am index 131bef1..8a2c56a 100644 --- a/src/hnbap/Makefile.am +++ b/src/hnbap/Makefile.am @@ -234,6 +234,8 @@ AM_CFLAGS = -I$(top_srcdir)/include $(ASN1C_CFLAGS) $(OSMOCORE_CFLAGS) +HNBAP_ASN1 = $(top_srcdir)/asn1/hnbap + noinst_LIBRARIES=libosmo-asn1-hnbap.a libosmo_asn1_hnbap_a_SOURCES=$(ASN_MODULE_SOURCES) libosmo_asn1_hnbap_a_LIBADD=$(ASN1C_LDADD) @@ -241,7 +243,7 @@ regen: regenerate-from-asn1-source regenerate-from-asn1-source: - asn1c -gen-PER -fnative-types $(top_srcdir)/asn1/hnbap/HNBAP-CommonDataTypes.asn $(top_srcdir)/asn1/hnbap/HNBAP-Constants.asn $(top_srcdir)/asn1/hnbap/HNBAP-IEs.asn $(top_srcdir)/asn1/hnbap/HNBAP-PDU.asn + asn1c -gen-PER -fnative-types $(HNBAP_ASN1)/HNBAP-CommonDataTypes.asn $(HNBAP_ASN1)/HNBAP-Constants.asn $(HNBAP_ASN1)/HNBAP-IEs.asn $(HNBAP_ASN1)/HNBAP-PDU.asn # remove the local copy of the runtime code -rm ANY.* BOOLEAN.* INTEGER.* NativeEnumerated.* NativeInteger.* OBJECT_IDENTIFIER.* asn_* OCTET_STRING.* converter-sample.c per_* xer_* constr* der_* ber_* BIT_STRING.* # change include style to `#include ' -- To view, visit https://gerrit.osmocom.org/786 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0507277995302261c87db1b0c48105065cf13ae4 Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: build: distcheck: add missing bits for testsuite distcheck In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: distcheck: add missing bits for testsuite distcheck ...................................................................... build: distcheck: add missing bits for testsuite distcheck Got some errors during 'make distcheck', copying the way openbsc.git does these things. Change-Id: I13d76cd56dfb8fe4eb02d6fcada78a9e3311b51b --- M src/tests/Makefile.am 1 file changed, 10 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index d36c018..2ba3e89 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -41,12 +41,22 @@ } >'$(srcdir)/package.m4' TESTSUITE = $(srcdir)/testsuite +EXTRA_DIST = testsuite.at $(TESTSUITE) $(srcdir)/package.m4 \ + test-helpers.err test-helpers.ok test-hnbap.ok test-ranap.ok DISTCLEANFILES = atconfig check-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) +installcheck-local: atconfig $(TESTSUITE) + $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \ + $(TESTSUITEFLAGS) + +clean-local: + test ! -f '$(TESTSUITE)' || \ + $(SHELL) '$(TESTSUITE)' --clean + AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te AUTOTEST = $(AUTOM4TE) --language=autotest -- To view, visit https://gerrit.osmocom.org/785 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I13d76cd56dfb8fe4eb02d6fcada78a9e3311b51b Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:33 +0000 Subject: [MERGED] osmo-iuh[master]: build: distcheck: look for asn1 in top_srcdir, not top_builddir In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: distcheck: look for asn1 in top_srcdir, not top_builddir ...................................................................... build: distcheck: look for asn1 in top_srcdir, not top_builddir Change-Id: Iebcff240ba2fae964dad2a2c481fcbfd29e14e69 --- M src/Makefile.am 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/Makefile.am b/src/Makefile.am index 3e309db..2779315 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = hnbap rua ranap tests # Build {hnbap,rua,ranap}_{encoder,decoder}.c using asn1tostruct -ASN1_ROOT = $(top_builddir)/asn1/ +ASN1_ROOT = $(top_srcdir)/asn1 ASN1TOSTRUCT = $(ASN1_ROOT)/utils/asn1tostruct.py BUILT_SOURCES = hnbap_decoder.c hnbap_encoder.c rua_decoder.c rua_encoder.c \ gen_hnbap.stamp gen_rua.stamp gen_ranap.stamp -- To view, visit https://gerrit.osmocom.org/784 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iebcff240ba2fae964dad2a2c481fcbfd29e14e69 Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: build: distcheck: add missing distclean files In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: distcheck: add missing distclean files ...................................................................... build: distcheck: add missing distclean files Change-Id: I24d72b2b1bae52a1b2cf8a989396d2aac31d119e --- M include/osmocom/hnbap/Makefile.am M include/osmocom/ranap/Makefile.am M include/osmocom/rua/Makefile.am M src/Makefile.am M src/tests/Makefile.am 5 files changed, 22 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbap/Makefile.am b/include/osmocom/hnbap/Makefile.am index 83654cb..cd9b720 100644 --- a/include/osmocom/hnbap/Makefile.am +++ b/include/osmocom/hnbap/Makefile.am @@ -115,3 +115,6 @@ U-RNTIQueryRequest.h \ U-RNTIQueryResponse.h \ UTRANCellID.h + +DISTCLEANFILES = \ + hnbap_ies_defs.h diff --git a/include/osmocom/ranap/Makefile.am b/include/osmocom/ranap/Makefile.am index 4728ac8..0f83e03 100644 --- a/include/osmocom/ranap/Makefile.am +++ b/include/osmocom/ranap/Makefile.am @@ -593,3 +593,6 @@ RANAP_VoiceSupportMatchIndicator.h ranapdir = $(includedir)/osmocom/ranap + +DISTCLEANFILES = \ + ranap_ies_defs.h diff --git a/include/osmocom/rua/Makefile.am b/include/osmocom/rua/Makefile.am index 8e8896d..49e2150 100644 --- a/include/osmocom/rua/Makefile.am +++ b/include/osmocom/rua/Makefile.am @@ -35,3 +35,6 @@ RUA_TriggeringMessage.h \ RUA_TypeOfError.h \ RUA_UnsuccessfulOutcome.h + +DISTCLEANFILES = \ + rua_ies_defs.h diff --git a/src/Makefile.am b/src/Makefile.am index ffdfef8..3e309db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,3 +83,14 @@ $(MAKE) -C hnbap regen $(MAKE) -C ranap regen $(MAKE) -C rua regen + +DISTCLEANFILES = \ + hnbap_decoder.c \ + hnbap_encoder.c \ + rua_decoder.c \ + rua_encoder.c \ + ranap_decoder.c \ + ranap_encoder.c \ + gen_hnbap.stamp \ + gen_rua.stamp \ + gen_ranap.stamp diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 0fd050f..d36c018 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -42,6 +42,8 @@ TESTSUITE = $(srcdir)/testsuite +DISTCLEANFILES = atconfig + check-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) -- To view, visit https://gerrit.osmocom.org/783 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I24d72b2b1bae52a1b2cf8a989396d2aac31d119e Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: build: fix ranap gen, use same for gen hnbap and rua gen In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: fix ranap gen, use same for gen hnbap and rua gen ...................................................................... build: fix ranap gen, use same for gen hnbap and rua gen fix extraneous rebuild for each make invocation: touch the ranap.stamp file in src/ as the make target suggests. fix for 'make distcheck': ranap gen: move generated sources to builddir, not srcdir. Thus we also -I the builddir include to pick up those headers. hnbap and rua have the same situation as ranap (they generate numerous files from a single make rule). Use the same makefile semantics for those two (commit for ranap gen omitted the same changes for hnbap and rua). The generated headers are thus moved to include/osmocom/*/, so adjust #include statements accordingly (*_common.h, *_ies_defs.h). Also move hnbap_common.h to include/osmocom/hnbap and rua_common.h to include/osmocom/rua, since the *_ies_defs.h want to include them; and since *_ies_defs.h are now in include/osmocom/*, we want a '' include now. Also adjust gitignore. Change-Id: I32213666fcdfc144008fa7d46497c0938d093e86 --- M .gitignore M include/osmocom/hnbap/Makefile.am R include/osmocom/hnbap/hnbap_common.h M include/osmocom/ranap/Makefile.am M include/osmocom/rua/Makefile.am R include/osmocom/rua/rua_common.h M src/.gitignore M src/Makefile.am M src/hnbap_common.c M src/hnbgw_hnbap.c M src/hnbgw_rua.c M src/rua_common.c M src/rua_msg_factory.c M src/tests/hnb-test-rua.c M src/tests/hnb-test.c M src/tests/test-hnbap.c 16 files changed, 51 insertions(+), 27 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index b2538a7..e1430f9 100644 --- a/.gitignore +++ b/.gitignore @@ -35,5 +35,9 @@ tags libosmo-ranap.pc m4 +gen_hnbap.stamp +gen_rua.stamp gen_ranap.stamp +include/osmocom/hnbap/hnbap_ies_defs.h +include/osmocom/rua/rua_ies_defs.h include/osmocom/ranap/ranap_ies_defs.h diff --git a/include/osmocom/hnbap/Makefile.am b/include/osmocom/hnbap/Makefile.am index 7ab5d7f..83654cb 100644 --- a/include/osmocom/hnbap/Makefile.am +++ b/include/osmocom/hnbap/Makefile.am @@ -1,4 +1,5 @@ noinst_HEADERS = \ + hnbap_common.h hnbap_ies_defs.h \ AccessResult.h \ Access-stratum-release-indicator.h \ AdditionalNeighbourInfoList.h \ diff --git a/src/hnbap_common.h b/include/osmocom/hnbap/hnbap_common.h similarity index 100% rename from src/hnbap_common.h rename to include/osmocom/hnbap/hnbap_common.h diff --git a/include/osmocom/ranap/Makefile.am b/include/osmocom/ranap/Makefile.am index 13f1e1c..4728ac8 100644 --- a/include/osmocom/ranap/Makefile.am +++ b/include/osmocom/ranap/Makefile.am @@ -3,8 +3,8 @@ # the build process wants this header file, it should first build # src/ranap_encoder.c and src/ranap_decoder.c. # This rule sucks: -ranap_ies_defs.h: $(top_builddir)/src/ranap_encoder.c - make -C $(top_builddir)/src/ ranap_encoder.c +ranap_ies_defs.h: + $(MAKE) -C $(top_builddir)/src/ gen_ranap.stamp ranap_HEADERS = \ ranap_ies_defs.h \ diff --git a/include/osmocom/rua/Makefile.am b/include/osmocom/rua/Makefile.am index 059dfb8..8e8896d 100644 --- a/include/osmocom/rua/Makefile.am +++ b/include/osmocom/rua/Makefile.am @@ -1,4 +1,5 @@ noinst_HEADERS = \ + rua_common.h rua_ies_defs.h \ RUA_Ansi-41-IDNNS.h \ RUA_Cause.h \ RUA_CauseMisc.h \ diff --git a/src/rua_common.h b/include/osmocom/rua/rua_common.h similarity index 100% rename from src/rua_common.h rename to include/osmocom/rua/rua_common.h diff --git a/src/.gitignore b/src/.gitignore index 9384c58..55bca01 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,13 +1,10 @@ hnbap_decoder.c hnbap_encoder.c -hnbap_ies_defs.h rua_decoder.c rua_encoder.c -rua_ies_defs.h ranap_decoder.c ranap_encoder.c -ranap_ies_defs.h hnbgw diff --git a/src/Makefile.am b/src/Makefile.am index 17e60e2..ffdfef8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,25 +3,48 @@ # Build {hnbap,rua,ranap}_{encoder,decoder}.c using asn1tostruct ASN1_ROOT = $(top_builddir)/asn1/ ASN1TOSTRUCT = $(ASN1_ROOT)/utils/asn1tostruct.py -BUILT_SOURCES = hnbap_decoder.c hnbap_encoder.c rua_decoder.c rua_encoder.c gen_ranap.stamp +BUILT_SOURCES = hnbap_decoder.c hnbap_encoder.c rua_decoder.c rua_encoder.c \ + gen_hnbap.stamp gen_rua.stamp gen_ranap.stamp -hnbap_encoder.c hnbap_decoder.c hnbap_ies_defs.h: $(ASN1_ROOT)/hnbap/HNBAP-PDU-Contents.asn $(ASN1TOSTRUCT) +gen_hnbap.stamp: $(ASN1_ROOT)/hnbap/HNBAP-PDU-Contents.asn $(ASN1TOSTRUCT) $(ASN1TOSTRUCT) -f $< +# We also need to replace the include in the newly generated .c files: + sed -i 's,^#include "hnbap_ies_defs.h",#include ,' hnbap_encoder.c hnbap_decoder.c + sed -i 's,^#include "hnbap_common.h",#include ,' hnbap_encoder.c hnbap_decoder.c hnbap_ies_defs.h + mv hnbap_ies_defs.h $(top_builddir)/include/osmocom/hnbap/ +# this is ugly ^. hnbap_ies_defs.h is generated from asn1tostruct.py here, but +# it should live in include/osmocom/hnbap/. + touch $(top_builddir)/src/$@ -rua_encoder.c rua_decoder.c rua_ies_defs.h: $(ASN1_ROOT)/rua/RUA-PDU-Contents.asn $(ASN1TOSTRUCT) +hnbap_decoder.c hnbap_encoder.c: gen_hnbap.stamp + +gen_rua.stamp: $(ASN1_ROOT)/rua/RUA-PDU-Contents.asn $(ASN1TOSTRUCT) $(ASN1TOSTRUCT) -p RUA_ -f $< +# We also need to replace the include in the newly generated .c files: + sed -i 's,^#include "rua_ies_defs.h",#include ,' rua_encoder.c rua_decoder.c + sed -i 's,^#include "rua_common.h",#include ,' rua_encoder.c rua_decoder.c rua_ies_defs.h + mv rua_ies_defs.h $(top_builddir)/include/osmocom/rua/ +# this is ugly ^. rua_ies_defs.h is generated from asn1tostruct.py here, but +# it should live in include/osmocom/rua/. + touch $(top_builddir)/src/$@ + +rua_decoder.c rua_encoder.c: gen_rua.stamp gen_ranap.stamp: $(ASN1_ROOT)/ranap/RANAP-PDU-Contents.asn $(ASN1TOSTRUCT) $(ASN1TOSTRUCT) -p RANAP_ -f $< # We also need to replace the include in the newly generated .c files: sed -i 's,^#include "ranap_ies_defs.h",#include ,' ranap_encoder.c ranap_decoder.c sed -i 's,^#include "ranap_common.h",#include ,' ranap_encoder.c ranap_decoder.c ranap_ies_defs.h - mv ranap_ies_defs.h $(top_srcdir)/include/osmocom/ranap/ + mv ranap_ies_defs.h $(top_builddir)/include/osmocom/ranap/ # this is ugly ^. ranap_ies_defs.h is generated from asn1tostruct.py here, but # it should live in include/osmocom/ranap/. - touch $(top_builddir)/$@ + touch $(top_builddir)/src/$@ -AM_CFLAGS = -I$(top_srcdir)/include $(OSMOCORE_CFLAGS) $(OSMOVTY_CFLAGS) $(OSMOGSM_CFLAGS) $(OSMONETIF_CFLAGS) $(ASN1C_CFLAGS) $(OSMOSIGTRAN_CFLAGS) +ranap_decoder.c ranap_encoder.c: gen_ranap.stamp + +AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ + $(OSMOCORE_CFLAGS) $(OSMOVTY_CFLAGS) $(OSMOGSM_CFLAGS) \ + $(OSMONETIF_CFLAGS) $(ASN1C_CFLAGS) $(OSMOSIGTRAN_CFLAGS) COMMON_LDADD = -lsctp # build the shared RANAP library @@ -37,9 +60,7 @@ # bin_PROGRAMS = osmo-hnbgw -noinst_HEADERS = hnbap_common.h hnbap_ies_defs.h \ - rua_common.h rua_ies_defs.h \ - context_map.h hnbgw.h hnbgw_cn.h \ +noinst_HEADERS = context_map.h hnbgw.h hnbgw_cn.h \ hnbgw_hnbap.h hnbgw_rua.h hnbgw_ranap.h osmo_hnbgw_SOURCES = hnbap_encoder.c hnbap_decoder.c hnbap_common.c \ diff --git a/src/hnbap_common.c b/src/hnbap_common.c index f321a1c..2cd6519 100644 --- a/src/hnbap_common.c +++ b/src/hnbap_common.c @@ -24,7 +24,7 @@ #include #include -#include "hnbap_common.h" +#include #include "hnbgw.h" static const struct value_string hnbap_cause_radio_vals[] = { diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 5246b81..c329fe4 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -28,11 +28,11 @@ #include #include "asn1helpers.h" +#include #include #include "hnbgw.h" -#include "hnbap_common.h" -#include "hnbap_ies_defs.h" +#include #define IU_MSG_NUM_IES 32 #define IU_MSG_NUM_EXT_IES 32 diff --git a/src/hnbgw_rua.c b/src/hnbgw_rua.c index a6f0100..fc22bfc 100644 --- a/src/hnbgw_rua.c +++ b/src/hnbgw_rua.c @@ -34,8 +34,8 @@ #include "hnbgw.h" #include "hnbgw_ranap.h" -#include "rua_common.h" -#include "rua_ies_defs.h" +#include +#include #include "context_map.h" static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg) diff --git a/src/rua_common.c b/src/rua_common.c index fcb873e..a5ab044 100644 --- a/src/rua_common.c +++ b/src/rua_common.c @@ -23,7 +23,7 @@ #include -#include "rua_common.h" +#include #include "hnbgw.h" extern int asn1_xer_print; diff --git a/src/rua_msg_factory.c b/src/rua_msg_factory.c index b664509..0bce326 100644 --- a/src/rua_msg_factory.c +++ b/src/rua_msg_factory.c @@ -1,8 +1,8 @@ #include #include -#include "rua_common.h" -#include "rua_ies_defs.h" +#include +#include #include "rua_msg_factory.h" #include "asn1helpers.h" #include "hnbgw.h" diff --git a/src/tests/hnb-test-rua.c b/src/tests/hnb-test-rua.c index 69c41eb..a218852 100644 --- a/src/tests/hnb-test-rua.c +++ b/src/tests/hnb-test-rua.c @@ -1,6 +1,6 @@ #include -#include "../rua_ies_defs.h" +#include #include "hnb-test-layers.h" diff --git a/src/tests/hnb-test.c b/src/tests/hnb-test.c index af87376..2c41199 100644 --- a/src/tests/hnb-test.c +++ b/src/tests/hnb-test.c @@ -52,8 +52,8 @@ #include "hnb-test.h" #include "hnb-test-layers.h" -#include "hnbap_common.h" -#include "hnbap_ies_defs.h" +#include +#include #include "rua_msg_factory.h" #include "asn1helpers.h" #include diff --git a/src/tests/test-hnbap.c b/src/tests/test-hnbap.c index c6e7d94..ef46070 100644 --- a/src/tests/test-hnbap.c +++ b/src/tests/test-hnbap.c @@ -22,8 +22,8 @@ #include #include "asn1helpers.h" -#include "hnbap_common.h" -#include "hnbap_ies_defs.h" +#include +#include #include "test_common.h" #include -- To view, visit https://gerrit.osmocom.org/782 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I32213666fcdfc144008fa7d46497c0938d093e86 Gerrit-PatchSet: 4 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: build: remove subdir-objects from configure.ac, it is broken In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: remove subdir-objects from configure.ac, it is broken ...................................................................... build: remove subdir-objects from configure.ac, it is broken This is a known autoconf bug, it creates odd directories named literally '$(top_srcdir)', potentially messing up dependency checking. Change-Id: Ia47b038d4ca4f6c345711fb17d074f71c80e4453 --- M configure.ac 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 0c3ba3e..249701e 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ LT_INIT -AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.9 subdir-objects tar-ustar]) +AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.9 tar-ustar]) dnl tar-ustar: some asn1 filenames surpass the 99 char limit of tar, so we need dnl to make tar allow longer filenames. -- To view, visit https://gerrit.osmocom.org/781 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia47b038d4ca4f6c345711fb17d074f71c80e4453 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: build: use tar-ustar to allow paths longer than 99 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: use tar-ustar to allow paths longer than 99 ...................................................................... build: use tar-ustar to allow paths longer than 99 Needed to fix these errors: tar: osmo-iuh-UNKNOWN-dirty/include/osmocom/ranap/RANAP_SourceeNodeB-ToTargeteNodeB-TransparentContainer.h: file name is too long (max 99); not dumped tar: osmo-iuh-UNKNOWN-dirty/include/osmocom/ranap/RANAP_LocationRelatedDataRequestTypeSpecificToGERANIuMode.h: file name is too long (max 99); not dumped tar: osmo-iuh-UNKNOWN-dirty/include/osmocom/ranap/RANAP_TargeteNodeB-ToSourceeNodeB-TransparentContainer.h: file name is too long (max 99); not dumped tar: osmo-iuh-UNKNOWN-dirty/include/osmocom/ranap/RANAP_Requested-RAB-Parameter-ExtendedGuaranteedBitrateList.h: file name is too long (max 99); not dumped Change-Id: Id41bca92810a81ac50697c0230a6caef490b0ffd --- M configure.ac 1 file changed, 4 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index c3a65d6..0c3ba3e 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,10 @@ LT_INIT -AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) +AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.9 subdir-objects tar-ustar]) +dnl tar-ustar: some asn1 filenames surpass the 99 char limit of tar, so we need +dnl to make tar allow longer filenames. + AC_CONFIG_TESTDIR(src/tests) dnl kernel style compile messages -- To view, visit https://gerrit.osmocom.org/780 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id41bca92810a81ac50697c0230a6caef490b0ffd Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: tests: don't log filename nor color in unit tests In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: tests: don't log filename nor color in unit tests ...................................................................... tests: don't log filename nor color in unit tests In experr, we had line numbers in log output, which might change. Also, for make distcheck, the path of the source file might have some '../../' added in the log output (to indicate the src dir as seen from the build dir). Fix both by dropping source file and line. Also drop color while at it. Change-Id: Ie76384c4176ce0a7d89d093f2efb848fe3f19400 --- M src/tests/test-helpers.err M src/tests/test_common.c 2 files changed, 5 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/tests/test-helpers.err b/src/tests/test-helpers.err index 81b79e1..891094a 100644 --- a/src/tests/test-helpers.err +++ b/src/tests/test-helpers.err @@ -1,3 +1,2 @@ -<0004> ranap_common.c:508 Invalid PLMN Identity size: should be 3, is 2 -<0004> ranap_common.c:522 Invalid LAC size: should be 2, is 1 - \ No newline at end of file +Invalid PLMN Identity size: should be 3, is 2 +Invalid LAC size: should be 2, is 1 diff --git a/src/tests/test_common.c b/src/tests/test_common.c index 4e4c10c..a79d5f5 100644 --- a/src/tests/test_common.c +++ b/src/tests/test_common.c @@ -85,4 +85,7 @@ exit(1); ranap_set_log_area(DRANAP); + + log_set_print_filename(osmo_stderr_target, 0); + log_set_use_color(osmo_stderr_target, 0); } -- To view, visit https://gerrit.osmocom.org/779 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie76384c4176ce0a7d89d093f2efb848fe3f19400 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:43:34 +0000 Subject: [MERGED] osmo-iuh[master]: jenkins.sh: don't build twice In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: jenkins.sh: don't build twice ...................................................................... jenkins.sh: don't build twice Instead of building the same .c files twice, rather verify that the 'make regen' target produces identical .c files as are checked in. Change-Id: I18e7677d8596f61b883e9db57b4bdd2a5c154ec3 --- M contrib/jenkins.sh 1 file changed, 14 insertions(+), 9 deletions(-) Approvals: Neels Hofmeyr: Verified Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index c24bec2..72efdbc 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -55,19 +55,24 @@ marker osmo-iuh cd "$base" -# Build using the checked-in asn1 code -autoreconf --install --force -./configure -$MAKE $PARALLEL_MAKE -LD_LIBRARY_PATH="$inst/lib" $MAKE check -# distcheck is broken -#LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck -make clean -# Build with regenerated asn1 code autoreconf --install --force ./configure + +# Verify that checked-in asn1 code is identical to regenerated asn1 code PATH="$inst/bin:$PATH" $MAKE $PARALLEL_MAKE -C src regen + +# attempt to settle the file system +sleep 1 + +git status +git diff | cat + +if ! git diff-files --quiet ; then + echo "ERROR: 'make -C src regen' does not match committed asn1 code" + exit 1 +fi + $MAKE $PARALLEL_MAKE LD_LIBRARY_PATH="$inst/lib" $MAKE check # distcheck is broken -- To view, visit https://gerrit.osmocom.org/776 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I18e7677d8596f61b883e9db57b4bdd2a5c154ec3 Gerrit-PatchSet: 7 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:45:21 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:45:21 +0000 Subject: osmo-bts[master]: dyn TS: if PCU is not connected, allow operation as TCH In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 Please add the "OML Report of channel act/deact failures" ticket. -- To view, visit https://gerrit.osmocom.org/748 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:45:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:45:27 +0000 Subject: [MERGED] osmo-bts[master]: dyn TS: if PCU is not connected, allow operation as TCH In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: dyn TS: if PCU is not connected, allow operation as TCH ...................................................................... dyn TS: if PCU is not connected, allow operation as TCH Before this patch, Osmocom style TCH/F_TCH/H_PDCH dyn TS were paralyzed if no PCU was running. The state of the dyn TS would lock up in the PDCH activation phase since the PCU never completed the process. Make more robust, i.e. don't concern the BSC with PDCH activation failures. This matches the way plain PDCH TS work: besides declaring the TS as PDCH, the BSC is not involved and is not told about errors. During PDCH deactivation, still wait for the PCU to tear down the PDTCH SAPIs, but in case no PCU is connected, send a rel ack right away. Thus, the BSC will happily switch Osmocom style dynamic timeslots to and from PDCH mode, using the dyn TS as voice channels as needed, and not caring about possible PDCH failures. GPRS starts working right away as soon as a PCU connects, regardless of dyn TS having been used for voice any number of times, and without another switchover needed. In detail: In rsl_rx_chan_activ(), upon receiving a PDCH activation, send an RSL chan act ack right away, unconditionally (with an explaining comment). Do not concern the Abis link with PDCH activation failures. Since we're acking right away now, drop the chan act ack that would follow after the PCU activation: as before dyn TS, only send acks and nacks for rel_act_kind == LCHAN_REL_ACT_RSL (PDCH runs as LCHAN_REL_ACT_PCU). In dyn_ts_pdch_release, indicate that the PCU is not connected by means of returning 1. In rsl_rx_rf_chan_rel(), use this indicator to send a rel ack right away if the PCU is not connected. Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 --- M src/common/rsl.c 1 file changed, 34 insertions(+), 11 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/rsl.c b/src/common/rsl.c index 8905028..559599f 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -606,14 +606,7 @@ /* Send an RSL Channel Activation Ack if cause is zero, a Nack otherwise. */ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause) { - /* - * Normally, PDCH activation via PCU does not ack back to the BSC. - * But for GSM_PCHAN_TCH_F_TCH_H_PDCH, send a non-standard act ack for - * LCHAN_REL_ACT_PCU, since the act req came from RSL initially. - */ - if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL - && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH - && lchan->rel_act_kind == LCHAN_REL_ACT_PCU)) { + if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) { LOGP(DRSL, LOGL_NOTICE, "%s not sending CHAN ACT %s\n", gsm_lchan_name(lchan), cause ? "NACK" : "ACK"); return 0; @@ -931,6 +924,29 @@ if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH && ts->dyn.pchan_want == GSM_PCHAN_PDCH) { /* + * We ack the activation to the BSC right away, regardless of + * the PCU succeeding or not; if a dynamic timeslot fails to go + * to PDCH mode for any reason, the BSC should still be able to + * switch it back to TCH modes and should not put the time slot + * in an error state. So for operating dynamic TS, the BSC + * would not take any action if the PDCH mode failed, e.g. + * because the PCU is not yet running. Even if alerting the + * core network of broken GPRS service is desired, this only + * makes sense when the PCU has not shown up for some time. + * It's easiest to not forward activation delays to the BSC: if + * the BSC tells us to do PDCH, we do our best, and keep the + * details on the BTS and PCU level. This is kind of analogous + * to how plain PDCH TS operate. Directly call + * rsl_tx_chan_act_ack() instead of rsl_tx_chan_act_acknack() + * because we don't want/need to decide whether to drop due to + * lchan->rel_act_kind. + */ + rc = rsl_tx_chan_act_ack(lchan); + if (rc < 0) + LOGP(DRSL, LOGL_ERROR, "%s Cannot send act ack: %d\n", + gsm_ts_and_pchan_name(ts), rc); + + /* * pcu_tx_info_ind() will pick up the ts->dyn.pchan_want. If * the PCU is not connected yet, ignore for now; the PCU will * catch up (and send the RSL ack) once it connects. @@ -981,7 +997,7 @@ /* PCU not connected yet. Just record the new type and done, * the PCU will pick it up once connected. */ ts->dyn.pchan_is = GSM_PCHAN_NONE; - return 0; + return 1; } return pcu_tx_info_ind(); @@ -990,6 +1006,8 @@ /* 8.4.14 RF CHANnel RELease is received */ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) { + int rc; + if (lchan->abis_ip.rtp_socket) { rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); @@ -1004,8 +1022,13 @@ /* Dynamic channel in PDCH mode is released via PCU */ if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH - && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) - return dyn_ts_pdch_release(lchan); + && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { + rc = dyn_ts_pdch_release(lchan); + if (rc != 1) + return rc; + /* If the PCU is not connected, continue right away. */ + return rsl_tx_rf_rel_ack(lchan); + } l1sap_chan_rel(lchan->ts->trx, chan_nr); -- To view, visit https://gerrit.osmocom.org/748 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:47:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:47:00 +0000 Subject: openbsc[master]: bts: extend bts_chan_load to allow counting tch only In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/793 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I86f1d502649747b6b9aefcb39081b14110e8f494 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:48:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:48:28 +0000 Subject: openbsc[master]: bsc: count the usage of codec by setting the lchan active In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/794/1/openbsc/include/openbsc/gsm_data.h File openbsc/include/openbsc/gsm_data.h: Line 190: [BSC_CTR_CODEC_AMR] = {"bts.codec_amr", "Count the usage of amr codec by channel mode requested."}, AMR/F and AMR/H as well as FR and HR codecs must be counted separately, sorry. So we need a total of five counters for all individual codecs. -- To view, visit https://gerrit.osmocom.org/794 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifc8a406a11dce16b9e7f3310841e470545550a2c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 9 06:49:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 9 Sep 2016 06:49:19 +0000 Subject: openbsc[master]: msc: add counters to track call attempts/active/success/failed In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/795 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I49b93af2e6a0ba16c2fb00b7b83974e8a6a16df3 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 09:38:07 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 09:38:07 +0000 Subject: [PATCH] libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS Message-ID: Review at https://gerrit.osmocom.org/841 gsm/gsm0503: migrate transcoding routines from OsmoBTS The GSM 05.03 transcoding routines are becoming increasingly popular, and some projects (such as GR-GSM and OsmocomBB) also require transcoding capabilities implemented within the libosmocore. Now there are the following data types supported: - xCCH - PDTCH (CS 2,3 and MCS 1-9) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc --- M include/Makefile.am A include/osmocom/gsm/gsm0503_coding.h A include/osmocom/gsm/gsm0503_interleaving.h A include/osmocom/gsm/gsm0503_mapping.h A include/osmocom/gsm/gsm0503_parity.h A include/osmocom/gsm/gsm0503_tables.h M src/gsm/Makefile.am A src/gsm/gsm0503_coding.c A src/gsm/gsm0503_interleaving.c A src/gsm/gsm0503_mapping.c A src/gsm/gsm0503_parity.c A src/gsm/gsm0503_tables.c M src/gsm/libosmogsm.map 13 files changed, 5,748 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/41/841/1 diff --git a/include/Makefile.am b/include/Makefile.am index c125691..6829378 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -69,6 +69,11 @@ osmocom/gsm/gsm0480.h \ osmocom/gsm/gsm0502.h \ osmocom/gsm/gsm0503.h \ + osmocom/gsm/gsm0503_tables.h \ + osmocom/gsm/gsm0503_parity.h \ + osmocom/gsm/gsm0503_mapping.h \ + osmocom/gsm/gsm0503_interleaving.h \ + osmocom/gsm/gsm0503_coding.h \ osmocom/gsm/gsm0808.h \ osmocom/gsm/gsm23003.h \ osmocom/gsm/gsm48.h \ diff --git a/include/osmocom/gsm/gsm0503_coding.h b/include/osmocom/gsm/gsm0503_coding.h new file mode 100644 index 0000000..b8eb205 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_coding.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include + +#define GSM0503_GPRS_BURSTS_NBITS (116 * 4) +#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4) +#define NUM_BYTES(N) ((N + 8 - 1) / 8) + +enum gsm0503_egprs_mcs { + EGPRS_MCS0, + EGPRS_MCS1, + EGPRS_MCS2, + EGPRS_MCS3, + EGPRS_MCS4, + EGPRS_MCS5, + EGPRS_MCS6, + EGPRS_MCS7, + EGPRS_MCS8, + EGPRS_MCS9, + EGPRS_NUM_MCS, +}; + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data); +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len); +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total); + +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, uint8_t *l2_data, + uint8_t l2_len); +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, + uint16_t nbits, uint8_t *usf_p, int *n_errors, int *n_bits_total); + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int net_order); +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order, + int efr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len); +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total); + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr); +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr); +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total); + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic); +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic); + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info); +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst); diff --git a/include/osmocom/gsm/gsm0503_interleaving.h b/include/osmocom/gsm/gsm0503_interleaving.h new file mode 100644 index 0000000..f97dff4 --- /dev/null +++ b/include/osmocom/gsm/gsm0503_interleaving.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB); +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB); +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB); + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB); +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB); +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB); + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di); + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di); +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di); diff --git a/include/osmocom/gsm/gsm0503_mapping.h b/include/osmocom/gsm/gsm0503_mapping.h new file mode 100644 index 0000000..4c6550a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_mapping.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn); +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn); + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd); +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd); + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B); +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B); + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B); +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B); + +void gsm0503_mcs5_burst_swap(sbit_t *eB); diff --git a/include/osmocom/gsm/gsm0503_parity.h b/include/osmocom/gsm/gsm0503_parity.h new file mode 100644 index 0000000..540124a --- /dev/null +++ b/include/osmocom/gsm/gsm0503_parity.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +const struct osmo_crc64gen_code gsm0503_fire_crc40; +const struct osmo_crc16gen_code gsm0503_cs234_crc16; +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr; +const struct osmo_crc16gen_code gsm0503_mcs_crc12; +const struct osmo_crc8gen_code gsm0503_rach_crc6; +const struct osmo_crc16gen_code gsm0503_sch_crc10; +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3; +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8; +const struct osmo_crc8gen_code gsm0503_amr_crc6; diff --git a/include/osmocom/gsm/gsm0503_tables.h b/include/osmocom/gsm/gsm0503_tables.h new file mode 100644 index 0000000..e6761ca --- /dev/null +++ b/include/osmocom/gsm/gsm0503_tables.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8]; +extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8]; +extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8]; +extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8]; +extern const ubit_t gsm0503_usf2six[8][6]; +extern const ubit_t gsm0503_usf2twelve_ubit[8][12]; +extern const sbit_t gsm0503_usf2twelve_sbit[8][12]; +extern const uint8_t gsm0503_puncture_cs2[588]; +extern const uint8_t gsm0503_puncture_cs3[676]; +extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108]; +extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117]; +extern const uint8_t gsm0503_puncture_mcs1_p1[588]; +extern const uint8_t gsm0503_puncture_mcs1_p2[588]; +extern const uint8_t gsm0503_puncture_mcs2_p1[732]; +extern const uint8_t gsm0503_puncture_mcs2_p2[732]; +extern const uint8_t gsm0503_puncture_mcs3_p1[948]; +extern const uint8_t gsm0503_puncture_mcs3_p2[948]; +extern const uint8_t gsm0503_puncture_mcs3_p3[948]; +extern const uint8_t gsm0503_puncture_mcs4_p1[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p2[1116]; +extern const uint8_t gsm0503_puncture_mcs4_p3[1116]; +extern const uint8_t gsm0503_puncture_mcs5_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs5_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs6_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs6_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135]; +extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162]; +extern const uint8_t gsm0503_puncture_mcs7_p1[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p2[1404]; +extern const uint8_t gsm0503_puncture_mcs7_p3[1404]; +extern const uint8_t gsm0503_puncture_mcs8_p1[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p2[1692]; +extern const uint8_t gsm0503_puncture_mcs8_p3[1692]; +extern const uint8_t gsm0503_puncture_mcs9_p1[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p2[1836]; +extern const uint8_t gsm0503_puncture_mcs9_p3[1836]; +extern const uint16_t gsm0503_interleave_mcs5[1248]; +extern const uint8_t gsm0503_gsm_fr_map[76]; +extern const uint8_t gsm0503_gsm_efr_protected_bits[65]; +extern const ubit_t gsm0503_afs_ic_ubit[4][8]; +extern const sbit_t gsm0503_afs_ic_sbit[4][8]; +extern const ubit_t gsm0503_ahs_ic_ubit[4][4]; +extern const sbit_t gsm0503_ahs_ic_sbit[4][4]; +extern const uint8_t gsm0503_tch_hr_interleaving[228][2]; +extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36]; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index d367c89..fa19e02 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -22,7 +22,9 @@ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c gsm0503_conv.c + gsup.c gprs_gea.c gsm0503_conv.c gsm0503_tables.c \ + gsm0503_parity.c gsm0503_mapping.c gsm0503_interleaving.c \ + gsm0503_coding.c gsm610.c gsm620.c gsm660.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -36,4 +38,12 @@ gsm0503_conv.c: $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py -CLEANFILES = gsm0503_conv.c +# Some libosmocodec dependences +gsm610.c: + $(AM_V_GEN)cp $(top_srcdir)/src/codec/gsm610.c ./ +gsm620.c: + $(AM_V_GEN)cp $(top_srcdir)/src/codec/gsm620.c ./ +gsm660.c: + $(AM_V_GEN)cp $(top_srcdir)/src/codec/gsm660.c ./ + +CLEANFILES = gsm0503_conv.c gsm610.c gsm620.c gsm660.c diff --git a/src/gsm/gsm0503_coding.c b/src/gsm/gsm0503_coding.c new file mode 100644 index 0000000..8351bc8 --- /dev/null +++ b/src/gsm/gsm0503_coding.c @@ -0,0 +1,2681 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2015 by Alexander Chemeris + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * EGPRS coding limits + */ + +/* Max header size with parity bits */ +#define EGPRS_HDR_UPP_MAX 54 + +/* Max encoded header size */ +#define EGPRS_HDR_C_MAX 162 + +/* Max punctured header size */ +#define EGPRS_HDR_HC_MAX 160 + +/* Max data block size with parity bits */ +#define EGPRS_DATA_U_MAX 612 + +/* Max encoded data block size */ +#define EGPRS_DATA_C_MAX 1836 + +/* Max single block punctured data size */ +#define EGPRS_DATA_DC_MAX 1248 + +/* Dual block punctured data size */ +#define EGPRS_DATA_C1 612 +#define EGPRS_DATA_C2 EGPRS_DATA_C1 + +/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ +#define GSM_FR_BYTES 33 +/* TS 101318 Chapter 5.2: 112 bits, no sig */ +#define GSM_HR_BYTES 14 +/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ +#define GSM_EFR_BYTES 31 + +union gprs_rlc_ul_hdr_egprs { + struct gprs_rlc_ul_header_egprs_1 type1; + struct gprs_rlc_ul_header_egprs_2 type2; + struct gprs_rlc_ul_header_egprs_3 type3; +}; + +union gprs_rlc_dl_hdr_egprs { + struct gprs_rlc_dl_header_egprs_1 type1; + struct gprs_rlc_dl_header_egprs_2 type2; + struct gprs_rlc_dl_header_egprs_3 type3; +}; + +struct gsm0503_mcs_code { + uint8_t mcs; + uint8_t usf_len; + + /* Header coding */ + uint8_t hdr_len; + uint8_t hdr_code_len; + uint8_t hdr_punc_len; + const struct osmo_conv_code *hdr_conv; + const uint8_t *hdr_punc; + + /* Data coding */ + uint16_t data_len; + uint16_t data_code_len; + uint16_t data_punc_len; + const struct osmo_conv_code *data_conv; + const uint8_t *data_punc[3]; +}; + +/* + * EGPRS UL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_ul_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .hdr_len = 31, + .hdr_code_len = 117, + .hdr_punc_len = 80, + .hdr_conv = &gsm0503_mcs1_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs1_ul_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 136, + .hdr_conv = &gsm0503_mcs5_ul_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .hdr_len = 46, + .hdr_code_len = 162, + .hdr_punc_len = 160, + .hdr_conv = &gsm0503_mcs7_ul_hdr, + .hdr_punc = gsm0503_puncture_mcs7_ul_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +/* + * EGPRS DL coding parameters + */ +struct gsm0503_mcs_code gsm0503_mcs_dl_codes[EGPRS_NUM_MCS] = { + { + .mcs = EGPRS_MCS0, + }, + { + .mcs = EGPRS_MCS1, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 178, + .data_code_len = 588, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs1, + .data_punc = { + gsm0503_puncture_mcs1_p1, + gsm0503_puncture_mcs1_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS2, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 226, + .data_code_len = 732, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs2, + .data_punc = { + gsm0503_puncture_mcs2_p1, + gsm0503_puncture_mcs2_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS3, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 298, + .data_code_len = 948, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs3, + .data_punc = { + gsm0503_puncture_mcs3_p1, + gsm0503_puncture_mcs3_p2, + gsm0503_puncture_mcs3_p3, + }, + }, + { + .mcs = EGPRS_MCS4, + .usf_len = 3, + .hdr_len = 28, + .hdr_code_len = 108, + .hdr_punc_len = 68, + .hdr_conv = &gsm0503_mcs1_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs1_dl_hdr, + + .data_len = 354, + .data_code_len = 1116, + .data_punc_len = 372, + .data_conv = &gsm0503_mcs4, + .data_punc = { + gsm0503_puncture_mcs4_p1, + gsm0503_puncture_mcs4_p2, + gsm0503_puncture_mcs4_p3, + }, + }, + { + .mcs = EGPRS_MCS5, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 450, + .data_code_len = 1404, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs5, + .data_punc = { + gsm0503_puncture_mcs5_p1, + gsm0503_puncture_mcs5_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS6, + .usf_len = 3, + .hdr_len = 25, + .hdr_code_len = 99, + .hdr_punc_len = 100, + .hdr_conv = &gsm0503_mcs5_dl_hdr, + .hdr_punc = NULL, + + .data_len = 594, + .data_code_len = 1836, + .data_punc_len = 1248, + .data_conv = &gsm0503_mcs6, + .data_punc = { + gsm0503_puncture_mcs6_p1, + gsm0503_puncture_mcs6_p2, + NULL, + }, + }, + { + .mcs = EGPRS_MCS7, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 900, + .data_code_len = 1404, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs7, + .data_punc = { + gsm0503_puncture_mcs7_p1, + gsm0503_puncture_mcs7_p2, + gsm0503_puncture_mcs7_p3, + } + }, + { + .mcs = EGPRS_MCS8, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1092, + .data_code_len = 1692, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs8, + .data_punc = { + gsm0503_puncture_mcs8_p1, + gsm0503_puncture_mcs8_p2, + gsm0503_puncture_mcs8_p3, + } + }, + { + .mcs = EGPRS_MCS9, + .usf_len = 3, + .hdr_len = 37, + .hdr_code_len = 135, + .hdr_punc_len = 124, + .hdr_conv = &gsm0503_mcs7_dl_hdr, + .hdr_punc = gsm0503_puncture_mcs7_dl_hdr, + + .data_len = 1188, + .data_code_len = 1836, + .data_punc_len = 612, + .data_conv = &gsm0503_mcs9, + .data_punc = { + gsm0503_puncture_mcs9_p1, + gsm0503_puncture_mcs9_p2, + gsm0503_puncture_mcs9_p3, + } + }, +}; + +static int osmo_conv_decode_ber(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output, + int *n_errors, int *n_bits_total) +{ + int res, i, coded_len; + ubit_t recoded[EGPRS_DATA_C_MAX]; + + res = osmo_conv_decode(code, input, output); + + if (n_bits_total || n_errors) { + coded_len = osmo_conv_encode(code, output, recoded); + OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len); + } + + /* Count bit errors */ + if (n_errors) { + *n_errors = 0; + for (i = 0; i < coded_len; i++) { + if (!((recoded[i] && input[i] < 0) || + (!recoded[i] && input[i] > 0)) ) + *n_errors += 1; + } + } + + if (n_bits_total) + *n_bits_total = coded_len; + + return res; +} + +static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB, + int *n_errors, int *n_bits_total) +{ + ubit_t conv[224]; + int rv; + + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 0; +} + +static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data) +{ + ubit_t conv[224]; + + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + return 0; +} + +/* + * GSM xCCH block transcoding + */ +int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[456]; + int i; + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL); + + gsm0503_xcch_deinterleave(cB, iB); + + return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total); +} + +int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data) +{ + ubit_t iB[456], cB[456], hl = 1, hn = 1; + int i; + + _xcch_encode_cB(cB, l2_data); + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn); + + return 0; +} + +/* + * EGPRS PDTCH UL block decoding + */ + +/* + * Type 3 - MCS-1,2,3,4 + * Unmapping and deinterleaving + */ +static int egprs_type3_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t iB[456], q[8]; + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + q + i * 2, q + i * 2 + 1); + } + + gsm0503_mcs1_ul_deinterleave(hc, dc, iB); + + return 0; +} + +/* + * Type 2 - MCS-5,6 + * Unmapping and deinterleaving + */ +static int egprs_type2_unmap(const sbit_t *bursts, sbit_t *hc, sbit_t *dc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_DC_MAX]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs5_ul_burst_unmap(di, burst, hi, i); + } + + gsm0503_mcs5_ul_deinterleave(hc, dc, hi, di); + + return 0; +} + +/* + * Type 1 - MCS-7,8,9 + * Unmapping and deinterleaving - Note that MCS-7 interleaver is unique + */ +static int egprs_type1_unmap(const sbit_t *bursts, sbit_t *hc, + sbit_t *c1, sbit_t *c2, int msc) +{ + int i; + sbit_t burst[348]; + sbit_t hi[EGPRS_HDR_HC_MAX]; + sbit_t di[EGPRS_DATA_C1 * 2]; + + for (i = 0; i < 4; i++) { + memcpy(burst, &bursts[i * 348], 348); + + gsm0503_mcs5_burst_swap(burst); + gsm0503_mcs7_ul_burst_unmap(di, burst, hi, i); + } + + if (msc == EGPRS_MCS7) + gsm0503_mcs7_ul_deinterleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_ul_deinterleave(hc, c1, c2, hi, di); + + return 0; +} + +/* + * Decode EGPRS UL header section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + */ +static int _egprs_decode_hdr(const sbit_t *hc, int mcs, + union gprs_rlc_ul_hdr_egprs *hdr) +{ + sbit_t C[EGPRS_HDR_C_MAX]; + ubit_t upp[EGPRS_HDR_UPP_MAX]; + int i, j, rc; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_ul_codes[mcs]; + + /* Skip depuncturing on MCS-5,6 header */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(C, hc, code->hdr_code_len); + goto hdr_conv_decode; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + i = code->hdr_code_len - 1; + j = code->hdr_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->hdr_punc[i]) + C[i] = hc[j--]; + else + C[i] = 0; + } + +hdr_conv_decode: + osmo_conv_decode_ber(code->hdr_conv, C, upp, NULL, NULL); + rc = osmo_crc8gen_check_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + if (rc) + return -1; + + osmo_ubit2pbit_ext((pbit_t *) hdr, 0, upp, 0, code->hdr_len, 1); + + return 0; +} + +/* + * Blind MCS header decoding based on burst length and CRC validation. + * Ignore 'q' value coding identification. This approach provides + * the strongest chance of header recovery. + */ +static int egprs_decode_hdr(union gprs_rlc_ul_hdr_egprs *hdr, + const sbit_t *bursts, uint16_t nbits) +{ + int rc; + sbit_t hc[EGPRS_HDR_HC_MAX]; + + if (nbits == GSM0503_GPRS_BURSTS_NBITS) { + /* MCS-1,2,3,4 */ + egprs_type3_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS1, hdr); + if (!rc) + return EGPRS_HDR_TYPE3; + } else if (nbits == GSM0503_EGPRS_BURSTS_NBITS) { + /* MCS-5,6 */ + egprs_type2_unmap(bursts, hc, NULL); + rc = _egprs_decode_hdr(hc, EGPRS_MCS5, hdr); + if (!rc) + return EGPRS_HDR_TYPE2; + + /* MCS-7,8,9 */ + egprs_type1_unmap(bursts, hc, NULL, NULL, EGPRS_MCS7); + rc = _egprs_decode_hdr(hc, EGPRS_MCS7, hdr); + if (!rc) + return EGPRS_HDR_TYPE1; + } + + return -1; +} + +/* + * Parse EGPRS UL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_ul_cps(struct egprs_cps *cps, + union gprs_rlc_ul_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = (hdr->type2.cps_lo << 2) | hdr->type2.cps_hi; + break; + case EGPRS_HDR_TYPE3: + bits = (hdr->type3.cps_lo << 2) | hdr->type3.cps_hi; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * Decode EGPRS UL data section + * + * 1. Depuncture + * 2. Convolutional decoding + * 3. CRC check + * 4. Block combining (MCS-7,8,9 only) + */ +static int egprs_decode_data(uint8_t *l2_data, sbit_t *c, + int mcs, int p, int blk, int *n_errors, int *n_bits_total) +{ + ubit_t u[EGPRS_DATA_U_MAX]; + sbit_t C[EGPRS_DATA_C_MAX]; + + int i, j, rc, data_len; + struct gsm0503_mcs_code *code; + + if (blk && mcs < EGPRS_MCS7) { + /* Invalid MCS-X block state */ + return -1; + } + + code = &gsm0503_mcs_ul_codes[mcs]; + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + /* + * MCS-1,6 - single block processing + * MCS-7,9 - dual block processing + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + i = code->data_code_len - 1; + j = code->data_punc_len - 1; + + for (; i >= 0; i--) { + if (!code->data_punc[p][i]) + C[i] = c[j--]; + else + C[i] = 0; + } + + osmo_conv_decode_ber(code->data_conv, C, u, n_errors, n_bits_total); + rc = osmo_crc16gen_check_bits(&gsm0503_mcs_crc12, u, + data_len, u + data_len); + if (rc) + return -1; + + /* Offsets output pointer on the second block of Type 1 MCS */ + osmo_ubit2pbit_ext(l2_data, code->hdr_len + blk * data_len, + u, 0, data_len, 1); + + /* Return the number of bytes required for the bit message */ + return NUM_BYTES(code->hdr_len + code->data_len); +} + +/* + * Decode EGPRS UL message + * + * 1. Header section decoding + * 2. Extract CPS settings + * 3. Burst unmapping and deinterleaving + * 4. Data section decoding + */ +int gsm0503_pdtch_egprs_decode(uint8_t *l2_data, sbit_t *bursts, uint16_t nbits, + uint8_t *usf_p, int *n_errors, int *n_bits_total) +{ + sbit_t dc[EGPRS_DATA_DC_MAX]; + sbit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + int type, rc; + struct egprs_cps cps; + union gprs_rlc_ul_hdr_egprs *hdr; + + if ((nbits != GSM0503_GPRS_BURSTS_NBITS) && + (nbits != GSM0503_EGPRS_BURSTS_NBITS)) { + /* Invalid EGPRS bit length */ + return -1; + } + + hdr = (union gprs_rlc_ul_hdr_egprs *) l2_data; + type = egprs_decode_hdr(hdr, bursts, nbits); + if (egprs_parse_ul_cps(&cps, hdr, type) < 0) + return -1; + + switch (cps.mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + egprs_type3_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + egprs_type2_unmap(bursts, NULL, dc); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + egprs_type1_unmap(bursts, NULL, c1, c2, cps.mcs); + break; + default: + /* Invalid MCS-X */ + return -1; + } + + /* Decode MCS-X block, where X = cps.mcs */ + if (cps.mcs < EGPRS_MCS7) { + rc = egprs_decode_data(l2_data, dc, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + } else { + /* MCS-7,8,9 block 1 */ + rc = egprs_decode_data(l2_data, c1, cps.mcs, cps.p[0], + 0, n_errors, n_bits_total); + if (rc < 0) + return -1; + + /* MCS-7,8,9 block 2 */ + rc = egprs_decode_data(l2_data, c2, cps.mcs, cps.p[1], + 1, n_errors, n_bits_total); + if (rc < 0) + return -1; + } + + return rc; +} + +/* + * GSM PDTCH block transcoding + */ + +int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[456], cB[676], hl_hn[8]; + ubit_t conv[456]; + int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */ + + for (i = 0; i < 4; i++) + gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j])); + + if (i == 0 || k < best) { + best = k; + cs = i+1; + } + } + + gsm0503_xcch_deinterleave(cB, iB); + + switch (cs) { + case 1: + osmo_conv_decode_ber(&gsm0503_xcch, cB, + conv, n_errors, n_bits_total); + + rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40, + conv, 184, conv + 184); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1); + + return 23; + case 2: + for (i = 587, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs2[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs2, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 271, conv + 3 + 271); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1); + + return 34; + case 3: + for (i = 675, j = 455; i >= 0; i--) { + if (!gsm0503_puncture_cs3[i]) + cB[i] = cB[j--]; + else + cB[i] = 0; + } + + osmo_conv_decode_ber(&gsm0503_cs3, cB, + conv, n_errors, n_bits_total); + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 6; j++) + k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[3] = usf & 1; + conv[4] = (usf >> 1) & 1; + conv[5] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 3, 315, conv + 3 + 315); + if (rv) + return -1; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1); + + return 40; + case 4: + for (i = 12; i < 456; i++) + conv[i] = (cB[i] < 0) ? 1 : 0; + + for (i = 0; i < 8; i++) { + for (j = 0, k = 0; j < 12; j++) + k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + usf = i; + } + } + + conv[9] = usf & 1; + conv[10] = (usf >> 1) & 1; + conv[11] = (usf >> 2) & 1; + if (usf_p) + *usf_p = usf; + + rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16, + conv + 9, 431, conv + 9 + 431); + if (rv) { + *n_bits_total = 456 - 12; + *n_errors = *n_bits_total; + return -1; + } + + *n_bits_total = 456 - 12; + *n_errors = 0; + + osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1); + + return 54; + default: + *n_bits_total = 0; + *n_errors = 0; + break; + } + + return -1; +} + +/* + * EGPRS PDTCH UL block encoding + */ +static int egprs_type3_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + ubit_t iB[456]; + const ubit_t *hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + gsm0503_mcs1_dl_interleave(gsm0503_usf2six[usf], hc, dc, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return 0; +} + +static int egprs_type2_map(ubit_t *bursts, ubit_t *hc, ubit_t *dc, int usf) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_DC_MAX]; + + gsm0503_mcs5_dl_interleave(hc, dc, hi, di); + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs5_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_type1_map(ubit_t *bursts, ubit_t *hc, + ubit_t *c1, ubit_t *c2, int usf, int mcs) +{ + int i; + const ubit_t *up; + ubit_t hi[EGPRS_HDR_HC_MAX]; + ubit_t di[EGPRS_DATA_C1 * 2]; + + if (mcs == EGPRS_MCS7) + gsm0503_mcs7_dl_interleave(hc, c1, c2, hi, di); + else + gsm0503_mcs8_dl_interleave(hc, c1, c2, hi, di); + + up = gsm0503_mcs5_usf_precode_table[usf]; + + for (i = 0; i < 4; i++) { + gsm0503_mcs7_dl_burst_map(di, &bursts[i * 348], hi, up, i); + gsm0503_mcs5_burst_swap((sbit_t *) &bursts[i * 348]); + } + + return 0; +} + +static int egprs_encode_hdr(ubit_t *hc, uint8_t *l2_data, int mcs) +{ + int i, j; + ubit_t upp[EGPRS_HDR_UPP_MAX], C[EGPRS_HDR_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + osmo_pbit2ubit_ext(upp, 0, l2_data, code->usf_len, code->hdr_len, 1); + osmo_crc8gen_set_bits(&gsm0503_mcs_crc8_hdr, upp, + code->hdr_len, upp + code->hdr_len); + + osmo_conv_encode(code->hdr_conv, upp, C); + + /* MCS-5,6 header direct puncture instead of table */ + if ((mcs == EGPRS_MCS5) || (mcs == EGPRS_MCS6)) { + memcpy(hc, C, code->hdr_code_len); + hc[99] = hc[98]; + return 0; + } + + if (!code->hdr_punc) { + /* Invalid MCS-X header puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->hdr_code_len; i++) { + if (!code->hdr_punc[i]) + hc[j++] = C[i]; + } + + return 0; +} + +static int egprs_encode_data(ubit_t *c, uint8_t *l2_data, + int mcs, int p, int blk) +{ + int i, j, data_len; + ubit_t u[EGPRS_DATA_U_MAX], C[EGPRS_DATA_C_MAX]; + struct gsm0503_mcs_code *code; + + code = &gsm0503_mcs_dl_codes[mcs]; + + /* + * Dual block - MCS-7,8,9 + * Single block - MCS-1,2,3,4,5,6 + */ + if (mcs >= EGPRS_MCS7) + data_len = code->data_len / 2; + else + data_len = code->data_len; + + osmo_pbit2ubit_ext(u, 0, l2_data, + code->usf_len + code->hdr_len + blk * data_len, data_len, 1); + + osmo_crc16gen_set_bits(&gsm0503_mcs_crc12, u, data_len, u + data_len); + + osmo_conv_encode(code->data_conv, u, C); + + if (!code->data_punc[p]) { + /* Invalid MCS-X data puncture matrix */ + return -1; + } + + for (i = 0, j = 0; i < code->data_code_len; i++) { + if (!code->data_punc[p][i]) + c[j++] = C[i]; + } + + return 0; +} + +/* + * Parse EGPRS DL header for coding and puncturing scheme (CPS) + * + * Type 1 - MCS-7,8,9 + * Type 2 - MCS-5,6 + * Type 3 - MCS-1,2,3,4 + */ +static int egprs_parse_dl_cps(struct egprs_cps *cps, + union gprs_rlc_dl_hdr_egprs *hdr, int type) +{ + uint8_t bits; + + switch (type) { + case EGPRS_HDR_TYPE1: + bits = hdr->type1.cps; + break; + case EGPRS_HDR_TYPE2: + bits = hdr->type2.cps; + break; + case EGPRS_HDR_TYPE3: + bits = hdr->type3.cps; + break; + default: + return -1; + } + + return egprs_get_cps(cps, type, bits); +} + +/* + * EGPRS DL message encoding + */ +int gsm0503_pdtch_egprs_encode(ubit_t *bursts, + uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t hc[EGPRS_DATA_C_MAX], dc[EGPRS_DATA_DC_MAX]; + ubit_t c1[EGPRS_DATA_C1], c2[EGPRS_DATA_C2]; + uint8_t mcs; + struct egprs_cps cps; + union gprs_rlc_dl_hdr_egprs *hdr; + + switch (l2_len) { + case 27: + mcs = EGPRS_MCS1; + break; + case 33: + mcs = EGPRS_MCS2; + break; + case 42: + mcs = EGPRS_MCS3; + break; + case 49: + mcs = EGPRS_MCS4; + break; + case 60: + mcs = EGPRS_MCS5; + break; + case 78: + mcs = EGPRS_MCS6; + break; + case 118: + mcs = EGPRS_MCS7; + break; + case 142: + mcs = EGPRS_MCS8; + break; + case 154: + mcs = EGPRS_MCS9; + break; + default: + return -1; + } + + /* Read header for USF and puncturing matrix selection. */ + hdr = (union gprs_rlc_dl_hdr_egprs *) l2_data; + + switch (mcs) { + case EGPRS_MCS1: + case EGPRS_MCS2: + case EGPRS_MCS3: + case EGPRS_MCS4: + /* Check for valid CPS and matching MCS to message size */ + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE3) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type3_map(bursts, hc, dc, hdr->type3.usf); + break; + case EGPRS_MCS5: + case EGPRS_MCS6: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE2) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(dc, l2_data, mcs, cps.p[0], 0); + egprs_type2_map(bursts, hc, dc, hdr->type2.usf); + break; + case EGPRS_MCS7: + case EGPRS_MCS8: + case EGPRS_MCS9: + if ((egprs_parse_dl_cps(&cps, hdr, EGPRS_HDR_TYPE1) < 0) || + (cps.mcs != mcs)) + goto bad_header; + + egprs_encode_hdr(hc, l2_data, mcs); + egprs_encode_data(c1, l2_data, mcs, cps.p[0], 0); + egprs_encode_data(c2, l2_data, mcs, cps.p[1], 1); + egprs_type1_map(bursts, hc, c1, c2, hdr->type1.usf, mcs); + break; + } + + return mcs >= EGPRS_MCS5 ? + GSM0503_EGPRS_BURSTS_NBITS : GSM0503_GPRS_BURSTS_NBITS; + +bad_header: + /* Invalid EGPRS MCS-X header */ + return -1; +} + +int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len) +{ + ubit_t iB[456], cB[676]; + const ubit_t *hl_hn; + ubit_t conv[334]; + int i, j, usf; + + switch (l2_len) { + case 23: + osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1); + + osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184); + + osmo_conv_encode(&gsm0503_xcch, conv, cB); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[0]; + + break; + case 34: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 271, conv + 3 + 271); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs2, conv, cB); + + for (i = 0, j = 0; i < 588; i++) + if (!gsm0503_puncture_cs2[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[1]; + + break; + case 40: + osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3, + 315, conv + 3 + 315); + + memcpy(conv, gsm0503_usf2six[usf], 6); + + osmo_conv_encode(&gsm0503_cs3, conv, cB); + + for (i = 0, j = 0; i < 676; i++) + if (!gsm0503_puncture_cs3[i]) + cB[j++] = cB[i]; + + hl_hn = gsm0503_pdtch_hl_hn_ubit[2]; + + break; + case 54: + osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1); + usf = l2_data[0] & 0x7; + + osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9, + 431, cB + 9 + 431); + + memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12); + + hl_hn = gsm0503_pdtch_hl_hn_ubit[3]; + + break; + default: + return -1; + } + + gsm0503_xcch_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], + hl_hn + i * 2, hl_hn + i * 2 + 1); + } + + return GSM0503_GPRS_BURSTS_NBITS; +} + +/* + * GSM TCH/F FR/EFR transcoding + */ + +static void tch_fr_reassemble(uint8_t *tch_data, + ubit_t *b_bits, int net_order) +{ + int i, j, k, l, o; + + tch_data[0] = 0xd << 4; + memset(tch_data + 1, 0, 32); + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); + + return; + } + + /* reassemble d-bits */ + i = 0; /* counts bits */ + j = 4; /* counts output bits */ + k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset input bits */ + while (i < 260) { + tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7))); + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l]-1; + } + i++; + j++; + } +} + +static void tch_fr_disassemble(ubit_t *b_bits, + uint8_t *tch_data, int net_order) +{ + int i, j, k, l, o; + + if (net_order) { + for (i = 0, j = 4; i < 260; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + + return; + } + + i = 0; /* counts bits */ + j = 4; /* counts input bits */ + k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */ + l = 0; /* counts element bits */ + o = 0; /* offset output bits */ + while (i < 260) { + b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; + if (--k < 0) { + o += gsm0503_gsm_fr_map[l]; + k = gsm0503_gsm_fr_map[++l] - 1; + } + i++; + j++; + } +} + +static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0x00; /* F = 0, FT = 000 */ + memset(tch_data + 1, 0, 14); + + for (i = 0, j = 8; i < 112; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 8; i < 112; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits) +{ + int i, j; + + tch_data[0] = 0xc << 4; + memset(tch_data + 1, 0, 30); + + for (i = 0, j = 4; i < 244; i++, j++) + tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7))); +} + +static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data) +{ + int i, j; + + for (i = 0, j = 4; i < 244; i++, j++) + b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len) +{ + int i, j; + + memset(tch_data, 0, (len + 7) >> 3); + + for (i = 0, j = 0; i < len; i++, j++) + tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7))); +} + +static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len) +{ + int i, j; + + for (i = 0, j = 0; i < len; i++, j++) + d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1; +} + +static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm610_bitorder[i]] = d_bits[i]; +} + +static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm610_bitorder[i]]; +} + +static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + const uint16_t *map; + + if (!b_bits[34] && !b_bits[35]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + d_bits[i] = b_bits[map[i]]; +} + +static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits) +{ + int i; + + for (i = 0; i < 260; i++) + b_bits[gsm660_bitorder[i]] = d_bits[i]; +} + +static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 260; i++) + d_bits[i] = b_bits[gsm660_bitorder[i]]; +} + +static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits) +{ + int i; + + for (i = 0; i < 65; i++) + b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1]; +} + +static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + int i; + + for (i = 0; i < 91; i++) { + d[i << 1] = u[i]; + d[(i << 1) + 1] = u[184 - i]; + } + + for (i = 0; i < 3; i++) + p[i] = u[91 + i]; +} + +static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + int i; + + for (i = 0; i < 91; i++) { + u[i] = d[i << 1]; + u[184 - i] = d[(i << 1) + 1]; + } + + for (i = 0; i < 3; i++) + u[91 + i] = p[i]; +} + +static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u) +{ + memcpy(d, u, 95); + memcpy(p, u + 95, 3); +} + +static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p) +{ + memcpy(u, d, 95); + memcpy(u + 95, p, 3); +} + +static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p) +{ + memcpy(w, s, 71); + w[71] = w[72] = s[69]; + memcpy(w + 73, s + 71, 50); + w[123] = w[124] = s[119]; + memcpy(w + 125, s + 121, 53); + w[178] = w[179] = s[172]; + memcpy(w + 180, s + 174, 50); + w[230] = w[231] = s[222]; + memcpy(w + 232, s + 224, 20); + memcpy(w + 252, p, 8); +} + +static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w) +{ + int sum; + + memcpy(s, w, 71); + sum = s[69] + w[71] + w[72]; + s[69] = (sum > 2); + memcpy(s + 71, w + 73, 50); + sum = s[119] + w[123] + w[124]; + s[119] = (sum > 2); + memcpy(s + 121, w + 125, 53); + sum = s[172] + w[178] + w[179]; + s[172] = (sum > 2); + memcpy(s + 174, w + 180, 50); + sum = s[220] + w[230] + w[231]; + s[222] = (sum > 2); + memcpy(s + 224, w + 232, 20); + memcpy(p, w + 252, 8); +} + +static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot) +{ + memcpy(u, d, prot); + memcpy(u + prot, p, 6); + memcpy(u + prot + 6, d + prot, len - prot); +} + +static void tch_amr_unmerge(ubit_t *d, ubit_t *p, + ubit_t *u, int len, int prot) +{ + memcpy(d, u, prot); + memcpy(p, u+prot, 6); + memcpy(d + prot, u + prot + 6, len - prot); +} + +int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, + int net_order, int efr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[185], s[244], w[260], b[65], d[260], p[8]; + int i, rv, len, steal = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return 23; + } + + osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total); + + tch_fr_unreorder(d, p, conv); + + for (i = 0; i < 78; i++) + d[i + 182] = (cB[i + 378] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p); + if (rv) { + /* Error checking CRC8 for the FR part of an EFR/FR frame */ + return -1; + } + + if (efr) { + tch_efr_d_to_w(w, d); + + tch_efr_unreorder(s, p, w); + + tch_efr_protected(s, b); + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p); + if (rv) { + /* Error checking CRC8 for the EFR part of an EFR frame */ + return -1; + } + + tch_efr_reassemble(tch_data, s); + + len = GSM_EFR_BYTES; + } else { + tch_fr_d_to_b(w, d); + + tch_fr_reassemble(tch_data, w, net_order); + + len = GSM_FR_BYTES; + } + + return len; +} + +int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, + int len, int net_order) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[185], w[260], b[65], s[244], d[260], p[8]; + int i; + + switch (len) { + case GSM_EFR_BYTES: /* TCH EFR */ + + tch_efr_disassemble(s, tch_data); + + tch_efr_protected(s, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p); + + tch_efr_reorder(w, s, p); + + tch_efr_w_to_d(d, w); + + goto coding_efr_fr; + case GSM_FR_BYTES: /* TCH FR */ + tch_fr_disassemble(w, tch_data, net_order); + + tch_fr_b_to_d(d, w); + +coding_efr_fr: + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p); + + tch_fr_reorder(conv, d, p); + + memcpy(cB + 378, d + 182, 78); + + osmo_conv_encode(&gsm0503_tch_fr, conv, cB); + + h = 0; + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + break; + default: + return -1; + } + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; +} + +int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i, rv, steal = 0; + + /* Only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* If we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total); + + tch_hr_unreorder(d, p, conv); + + for (i = 0; i < 17; i++) + d[i + 95] = (cB[i + 211] < 0) ? 1 : 0; + + rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + if (rv) { + /* Error checking CRC8 for an HR frame */ + return -1; + } + + tch_hr_d_to_b(b, d); + + tch_hr_reassemble(tch_data, b); + + return 15; +} + +int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len) +{ + ubit_t iB[912], cB[456], h; + ubit_t conv[98], b[112], d[112], p[3]; + int i; + + switch (len) { + case 15: /* TCH HR */ + tch_hr_disassemble(b, tch_data); + + tch_hr_b_to_d(d, b); + + osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p); + + tch_hr_reorder(conv, d, p); + + osmo_conv_encode(&gsm0503_tch_hr, conv, cB); + + memcpy(cB + 211, d + 95, 17); + + h = 0; + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 1); + } + + break; + case GSM_MACBLOCK_LEN: /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i=0; i<6; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + for (i=2; i<4; i++) { + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + } + + break; + default: + return -1; + } + + return 0; +} + +int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + *n_errors = 0; *n_bits_total = 0; + + for (i=0; i<8; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + steal -= h; + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + if (steal > 0) { + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 8; j++) + k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 7: /* TCH/AFS12.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 244, 81); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p); + if (rv) { + /* Error checking CRC8 for an AMR 12.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 244); + + len = 31; + + break; + case 6: /* TCH/AFS10.2 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 204, 65); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p); + if (rv) { + /* Error checking CRC8 for an AMR 10.2 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 204); + + len = 26; + + break; + case 5: /* TCH/AFS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 159, 75); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AFS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 148, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AFS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 134, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AFS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 118, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AFS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 103, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AFS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 95, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 448; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[250]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + goto facch; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID is not in codec list! */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID is not in codec list! */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 7: /* TCH/AFS12.2 */ + if (len != 31) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 244); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p); + + tch_amr_merge(conv, d, p, 244, 81); + + osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8); + + break; + case 6: /* TCH/AFS10.2 */ + if (len != 26) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 204); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p); + + tch_amr_merge(conv, d, p, 204, 65); + + osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8); + + break; + case 5: /* TCH/AFS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p); + + tch_amr_merge(conv, d, p, 159, 75); + + osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8); + + break; + case 4: /* TCH/AFS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 148, 61); + + osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8); + + break; + case 3: /* TCH/AFS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 134, 55); + + osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8); + + break; + case 2: /* TCH/AFS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 118, 55); + + osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8); + + break; + case 1: /* TCH/AFS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 103, 49); + + osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8); + + break; + case 0: /* TCH/AFS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 95, 39); + + osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 8); + +facch: + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 8; i++) { + gsm0503_tch_burst_map(&iB[i * 114], + &bursts[i * 116], &h, i >> 2); + } + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft, + uint8_t *cmr, int *n_errors, int *n_bits_total) +{ + sbit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i, j, k, best = 0, rv, len, steal = 0, id = 0; + + /* only unmap the stealing bits */ + if (!odd) { + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0); + steal -= h; + } + for (i = 2; i < 5; i++) { + gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1); + steal -= h; + } + } + + /* if we found a stole FACCH, but only at correct alignment */ + if (steal > 0) { + for (i = 0; i < 6; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 2); + } + + for (i = 2; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114 + 456], + &bursts[i * 116], NULL, 1); + } + + gsm0503_tch_fr_deinterleave(cB, iB); + + rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total); + if (rv) { + /* Error decoding FACCH frame */ + return -1; + } + + return GSM_MACBLOCK_LEN; + } + + for (i = 0; i < 4; i++) { + gsm0503_tch_burst_unmap(&iB[i * 114], + &bursts[i * 116], NULL, i >> 1); + } + + gsm0503_tch_hr_deinterleave(cB, iB); + + for (i = 0; i < 4; i++) { + for (j = 0, k = 0; j < 4; j++) + k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j])); + + if (i == 0 || k < best) { + best = k; + id = i; + } + } + + /* Check if indicated codec fits into range of codecs */ + if (id >= codecs) { + /* Codec mode out of range, return id */ + return id; + } + + switch ((codec_mode_req) ? codec[*ft] : codec[id]) { + case 5: /* TCH/AHS7.95 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 123, 67); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.95 frame */ + return -1; + } + + for (i = 0; i < 36; i++) + d[i + 123] = (cB[i + 192] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 159); + + len = 20; + + break; + case 4: /* TCH/AHS7.4 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 120, 61); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p); + if (rv) { + /* Error checking CRC8 for an AMR 7.4 frame */ + return -1; + } + + for (i = 0; i < 28; i++) + d[i + 120] = (cB[i + 200] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 148); + + len = 19; + + break; + case 3: /* TCH/AHS6.7 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 110, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 6.7 frame */ + return -1; + } + + for (i = 0; i < 24; i++) + d[i + 110] = (cB[i + 204] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 134); + + len = 17; + + break; + case 2: /* TCH/AHS5.9 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 102, 55); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.9 frame */ + return -1; + } + + for (i = 0; i < 16; i++) + d[i + 102] = (cB[i + 212] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 118); + + len = 15; + + break; + case 1: /* TCH/AHS5.15 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 91, 49); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p); + if (rv) { + /* Error checking CRC8 for an AMR 5.15 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 91] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 103); + + len = 13; + + break; + case 0: /* TCH/AHS4.75 */ + osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4, + conv, n_errors, n_bits_total); + + tch_amr_unmerge(d, p, conv, 83, 39); + + rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p); + if (rv) { + /* Error checking CRC8 for an AMR 4.75 frame */ + return -1; + } + + for (i = 0; i < 12; i++) + d[i + 83] = (cB[i + 216] < 0) ? 1 : 0; + + tch_amr_reassemble(tch_data, d, 95); + + len = 12; + + break; + default: + /* Unknown frame type */ + *n_bits_total = 159; + *n_errors = *n_bits_total; + return -1; + } + + /* Change codec request / indication, if frame is valid */ + if (codec_mode_req) + *cmr = id; + else + *ft = id; + + return len; +} + +int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len, + int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, + uint8_t cmr) +{ + ubit_t iB[912], cB[456], h; + ubit_t d[244], p[6], conv[135]; + int i; + uint8_t id; + + if (len == GSM_MACBLOCK_LEN) { /* FACCH */ + _xcch_encode_cB(cB, tch_data); + + h = 1; + + gsm0503_tch_fr_interleave(cB, iB); + + for (i = 0; i < 6; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], + &h, i >> 2); + for (i = 2; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114 + 456], + &bursts[i * 116], &h, 1); + + return 0; + } + + h = 0; + + if (codec_mode_req) { + if (cmr >= codecs) { + /* FIXME: CMR ID %d not in codec list */ + return -1; + } + id = cmr; + } else { + if (ft >= codecs) { + /* FIXME: FT ID %d not in codec list */ + return -1; + } + id = ft; + } + + switch (codec[ft]) { + case 5: /* TCH/AHS7.95 */ + if (len != 20) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 159); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p); + + tch_amr_merge(conv, d, p, 123, 67); + + osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4); + + memcpy(cB + 192, d + 123, 36); + + break; + case 4: /* TCH/AHS7.4 */ + if (len != 19) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 148); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p); + + tch_amr_merge(conv, d, p, 120, 61); + + osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4); + + memcpy(cB + 200, d + 120, 28); + + break; + case 3: /* TCH/AHS6.7 */ + if (len != 17) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 134); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 110, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4); + + memcpy(cB + 204, d + 110, 24); + + break; + case 2: /* TCH/AHS5.9 */ + if (len != 15) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 118); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p); + + tch_amr_merge(conv, d, p, 102, 55); + + osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4); + + memcpy(cB + 212, d + 102, 16); + + break; + case 1: /* TCH/AHS5.15 */ + if (len != 13) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 103); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p); + + tch_amr_merge(conv, d, p, 91, 49); + + osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4); + + memcpy(cB + 216, d + 91, 12); + + break; + case 0: /* TCH/AHS4.75 */ + if (len != 12) + goto invalid_length; + + tch_amr_disassemble(d, tch_data, 95); + + osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p); + + tch_amr_merge(conv, d, p, 83, 39); + + osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4); + + memcpy(cB + 216, d + 83, 12); + + break; + default: + /* FIXME: FT %ft is not supported */ + return -1; + } + + memcpy(cB, gsm0503_afs_ic_ubit[id], 4); + + gsm0503_tch_hr_interleave(cB, iB); + + for (i = 0; i < 4; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1); + + return 0; + +invalid_length: + /* FIXME: payload length %len does not comply with codec type %ft */ + return -1; +} + +/* + * GSM RACH transcoding + */ + +/* + * GSM RACH apply BSIC to parity + * + * p(j) = p(j) xor b(j) j = 0, ..., 5 + * b(0) = MSB of PLMN colour code + * b(5) = LSB of BS colour code + */ +static int rach_apply_bsic(ubit_t *d, uint8_t bsic) +{ + int i; + + /* Apply it */ + for (i = 0; i < 6; i++) + d[8 + i] ^= ((bsic >> (5 - i)) & 1); + + return 0; +} + +int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic) +{ + ubit_t conv[14]; + int rv; + + osmo_conv_decode(&gsm0503_rach, burst, conv); + + rach_apply_bsic(conv, bsic); + + rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + if (rv) + return -1; + + osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1); + + return 0; +} + +int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic) +{ + ubit_t conv[14]; + + osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1); + + osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8); + + rach_apply_bsic(conv, bsic); + + osmo_conv_encode(&gsm0503_rach, conv, burst); + + return 0; +} + +/* + * GSM SCH transcoding + */ +int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst) +{ + ubit_t conv[35]; + int rv; + + osmo_conv_decode(&gsm0503_sch, burst, conv); + + rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + if (rv) + return -1; + + osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1); + + return 0; +} + +int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info) +{ + ubit_t conv[35]; + + osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1); + + osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25); + + osmo_conv_encode(&gsm0503_sch, conv, burst); + + return 0; +} diff --git a/src/gsm/gsm0503_interleaving.c b/src/gsm/gsm0503_interleaving.c new file mode 100644 index 0000000..b5733ab --- /dev/null +++ b/src/gsm/gsm0503_interleaving.c @@ -0,0 +1,573 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include +#include + +/* + * GSM xCCH interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 4 blocks of 114 bits: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 4) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 456; k++) { + B = k & 3; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc, + sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k = 0; k < 25; k++) + c[k] = cp[k]; + for (k = 26; k < 82; k++) + c[k - 1] = cp[k]; + for (k = 83; k < 139; k++) + c[k - 2] = cp[k]; + for (k = 140; k < 424; k++) + c[k - 3] = cp[k]; + for (k = 425; k < 456; k++) + c[k - 4] = cp[k]; + + if (u) { + for (k = 0; k < 12; k++) + u[k] = c[k]; + } + + if (hc) { + for (k = 12; k < 80; k++) + hc[k - 12] = c[k]; + } + + if (dc) { + for (k = 80; k < 452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc, + const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k = 0; k < 12; k++) + c[k] = up[k]; + for (k = 12; k < 80; k++) + c[k] = hc[k - 12]; + for (k = 80; k < 452; k++) + c[k] = dc[k - 80]; + + for (k = 0; k < 25; k++) + cp[k] = c[k]; + for (k = 26; k < 82; k++) + cp[k] = c[k - 1]; + for (k = 83; k < 139; k++) + cp[k] = c[k - 2]; + for (k = 140; k < 424; k++) + cp[k] = c[k - 3]; + for (k = 425; k < 456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB) +{ + int k; + sbit_t c[452]; + sbit_t cp[456]; + + gsm0503_xcch_deinterleave(cp, iB); + + for (k = 0; k < 25; k++) + c[k] = cp[k]; + for (k = 26; k < 82; k++) + c[k - 1] = cp[k]; + for (k = 83; k < 139; k++) + c[k - 2] = cp[k]; + for (k = 140; k < 424; k++) + c[k - 3] = cp[k]; + for (k = 425; k < 456; k++) + c[k - 4] = cp[k]; + + if (hc) { + for (k = 0; k < 80; k++) + hc[k] = c[k]; + } + + if (dc) { + for (k = 80; k < 452; k++) + dc[k - 80] = c[k]; + } +} + +void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB) +{ + int k; + ubit_t c[452]; + ubit_t cp[456]; + + for (k = 0; k < 80; k++) + c[k] = hc[k]; + for (k = 80; k < 452; k++) + c[k] = dc[k - 80]; + + for (k = 0; k < 25; k++) + cp[k] = c[k]; + for (k = 26; k < 82; k++) + cp[k] = c[k - 1]; + for (k = 83; k < 139; k++) + cp[k] = c[k - 2]; + for (k = 140; k < 424; k++) + cp[k] = c[k - 3]; + for (k = 425; k < 456; k++) + cp[k] = c[k - 4]; + + cp[25] = 0; + cp[82] = 0; + cp[139] = 0; + cp[424] = 0; + + gsm0503_xcch_interleave(cp, iB); +} + +void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k = 0; k < 136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hi[j] = hc[k]; + } + + /* Data */ + for (k = 0; k < 1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k = 0; k < 136; k++) { + j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k = 0; k < 1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc, + ubit_t *hi, ubit_t *di) +{ + int j, k; + + /* Header */ + for (k = 0; k < 100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hi[j] = hc[k]; + } + + /* Data */ + for (k = 0; k < 1248; k++) { + j = gsm0503_interleave_mcs5[k]; + di[j] = dc[k]; + } +} + +void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + + /* Header */ + if (hc) { + for (k = 0; k < 100; k++) { + j = 25 * (k % 4) + ((17 * k) % 25); + hc[k] = hi[j]; + } + } + + /* Data */ + if (dc) { + for (k = 0; k < 1248; k++) { + j = gsm0503_interleave_mcs5[k]; + dc[k] = di[j]; + } + } +} + +void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k = 0; k < 124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k = 0; k < 1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + + +void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k = 0; k < 124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k = 0; k < 1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k = 0; k < 160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k = 0; k < 1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k = 0; k < 160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k = 0; k < 1224; k++) { + j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) + + (k + 2 - k / 408) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k = 0; k < 160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k = 0; k < 1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k = 0; k < 160; k++) { + j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4; + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k = 0; k < 1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1, + const ubit_t *c2, ubit_t *hi, ubit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + for (k = 0; k < 124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hi[j] = hc[k]; + } + + memcpy(&dc[0], c1, 612); + memcpy(&dc[612], c2, 612); + + /* Data */ + for (k = 0; k < 1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + di[j] = dc[k]; + } +} + +void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2, + const sbit_t *hi, const sbit_t *di) +{ + int j, k; + ubit_t dc[1224]; + + /* Header */ + if (hc) { + for (k = 0; k < 124; k++) { + j = 31 * (k % 4) + ((17 * k) % 31); + hc[k] = hi[j]; + } + } + + /* Data */ + if (c1 && c2) { + for (k = 0; k < 1224; k++) { + j = 306 * (2 * (k / 612) + (k % 2)) + + 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3; + dc[k] = di[j]; + } + + memcpy(c1, &dc[0], 612); + memcpy(c2, &dc[612], 612); + } +} + +/* + * GSM TCH FR/EFR/AFS interleaving and burst mapping + * + * Interleaving: + * + * Given 456 coded input bits, form 8 blocks of 114 bits, + * where even bits of the first 4 blocks and odd bits of the last 4 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 455 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 4n + (k mod 8) + * j = 2(49k mod 57) + ((k mod 8) div 4) + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 456; k++) { + B = k & 7; + j = 2 * ((49 * k) % 57) + ((k & 7) >> 2); + iB[B * 114 + j] = cB[k]; + } +} + +/* + * GSM TCH HR/AHS interleaving and burst mapping + * + * Interleaving: + * + * Given 288 coded input bits, form 4 blocks of 114 bits, + * where even bits of the first 2 blocks and odd bits of the last 2 blocks + * are used: + * + * i(B, j) = c(n, k) k = 0, ..., 227 + * n = 0, ..., N, N + 1, ... + * B = B_0 + 2n + b + * j, b = table[k]; + * + * Mapping on Burst: + * + * e(B, j) = i(B, j) + * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 + * e(B, 57) = h_l(B) + * e(B, 58) = h_n(B) + * + * Where hl(B) and hn(B) are bits in burst B indicating flags. + */ + +void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + cB[k] = iB[B * 114 + j]; + } +} + +void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB) +{ + int j, k, B; + + for (k = 0; k < 228; k++) { + B = gsm0503_tch_hr_interleaving[k][1]; + j = gsm0503_tch_hr_interleaving[k][0]; + iB[B * 114 + j] = cB[k]; + } +} diff --git a/src/gsm/gsm0503_mapping.c b/src/gsm/gsm0503_mapping.c new file mode 100644 index 0000000..d67d973 --- /dev/null +++ b/src/gsm/gsm0503_mapping.c @@ -0,0 +1,291 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include +#include + +#include +#include + +void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB, + sbit_t *hl, sbit_t *hn) +{ + memcpy(iB, eB, 57); + memcpy(iB + 57, eB + 59, 57); + + if (hl) + *hl = eB[57]; + + if (hn) + *hn = eB[58]; +} + +void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl, + const ubit_t *hn) +{ + memcpy(eB, iB, 57); + memcpy(eB + 59, iB + 57, 57); + + if (hl) + eB[57] = *hl; + if (hn) + eB[58] = *hn; +} + +void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (iB) { + for (i = odd; i < 57; i += 2) + iB[i] = eB[i]; + for (i = 58 - odd; i < 114; i += 2) + iB[i] = eB[i + 2]; + } + + if (h) { + if (!odd) + *h = eB[58]; + else + *h = eB[57]; + } +} + +void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd) +{ + int i; + + /* brainfuck: only copy even or odd bits */ + if (eB) { + for (i = odd; i < 57; i += 2) + eB[i] = iB[i]; + for (i = 58 - odd; i < 114; i += 2) + eB[i + 2] = iB[i]; + } + + if (h) { + if (!odd) + eB[58] = *h; + else + eB[57] = *h; + } +} + +void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, }; + + for (j = 0; j < 156; j++) + eB[j] = di[312 * B + j]; + for (j = 156; j < 168; j++) + eB[j] = hi[25 * B + j - 156]; + for (j = 168; j < 174; j++) + eB[j] = up[9 * B + j - 168]; + for (j = 174; j < 176; j++) + eB[j] = q[2 * B + j - 174]; + for (j = 176; j < 179; j++) + eB[j] = up[9 * B + j - 170]; + for (j = 179; j < 192; j++) + eB[j] = hi[25 * B + j - 167]; + for (j = 192; j < 348; j++) + eB[j] = di[312 * B + j - 36]; +} + +void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j = 0; j < 156; j++) + di[312 * B + j] = eB[j]; + for (j = 156; j < 168; j++) + hi[25 * B + j - 156] = eB[j]; + for (j = 168; j < 174; j++) + up[9 * B + j - 168] = eB[j]; + + for (j = 176; j < 179; j++) + up[9 * B + j - 170] = eB[j]; + for (j = 179; j < 192; j++) + hi[25 * B + j - 167] = eB[j]; + for (j = 192; j < 348; j++) + di[312 * B + j - 36] = eB[j]; +} + +void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + + for (j = 0; j < 156; j++) + eB[j] = di[312 * B + j]; + for (j = 156; j < 174; j++) + eB[j] = hi[34 * B + j - 156]; + for (j = 174; j < 176; j++) + eB[j] = 0; + for (j = 176; j < 192; j++) + eB[j] = hi[34 * B + j - 158]; + for (j = 192; j < 348; j++) + eB[j] = di[312 * B + j - 36]; +} + +void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j = 0; j < 156; j++) + di[312 * B + j] = eB[j]; + for (j = 156; j < 174; j++) + hi[34 * B + j - 156] = eB[j]; + for (j = 176; j < 192; j++) + hi[34 * B + j - 158] = eB[j]; + for (j = 192; j < 348; j++) + di[312 * B + j - 36] = eB[j]; +} + +void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, const ubit_t *up, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j = 0; j < 153; j++) + eB[j] = di[306 * B + j]; + for (j = 153; j < 168; j++) + eB[j] = hi[31 * B + j - 153]; + for (j = 168; j < 174; j++) + eB[j] = up[9 * B + j - 168]; + for (j = 174; j < 176; j++) + eB[j] = q[2 * B + j - 174]; + for (j = 176; j < 179; j++) + eB[j] = up[9 * B + j - 170]; + for (j = 179; j < 195; j++) + eB[j] = hi[31 * B + j - 164]; + for (j = 195; j < 348; j++) + eB[j] = di[306 * B + j - 42]; +} + +void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, sbit_t *up, int B) +{ + int j; + + for (j = 0; j < 153; j++) + di[306 * B + j] = eB[j]; + for (j = 153; j < 168; j++) + hi[31 * B + j - 153] = eB[j]; + for (j = 168; j < 174; j++) + up[9 * B + j - 168] = eB[j]; + + for (j = 176; j < 179; j++) + up[9 * B + j - 170] = eB[j]; + for (j = 179; j < 195; j++) + hi[31 * B + j - 164] = eB[j]; + for (j = 195; j < 348; j++) + di[306 * B + j - 42] = eB[j]; +} + +void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB, + const ubit_t *hi, int B) +{ + int j; + int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, }; + + for (j = 0; j < 153; j++) + eB[j] = di[306 * B + j]; + for (j = 153; j < 174; j++) + eB[j] = hi[40 * B + j - 153]; + for (j = 174; j < 176; j++) + eB[j] = q[2 * B + j - 174]; + for (j = 176; j < 195; j++) + eB[j] = hi[40 * B + j - 155]; + for (j = 195; j < 348; j++) + eB[j] = di[306 * B + j - 42]; +} + +void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB, + sbit_t *hi, int B) +{ + int j; + + for (j = 0; j < 153; j++) + di[306 * B + j] = eB[j]; + for (j = 153; j < 174; j++) + hi[40 * B + j - 153] = eB[j]; + + for (j = 176; j < 195; j++) + hi[40 * B + j - 155] = eB[j]; + for (j = 195; j < 348; j++) + di[306 * B + j - 42] = eB[j]; +} + +void gsm0503_mcs5_burst_swap(sbit_t *eB) +{ + sbit_t t[14]; + + t[0] = eB[155]; + t[1] = eB[158]; + t[2] = eB[161]; + t[3] = eB[164]; + t[4] = eB[167]; + t[5] = eB[170]; + t[6] = eB[173]; + t[7] = eB[195]; + t[8] = eB[196]; + t[9] = eB[198]; + t[10] = eB[199]; + t[11] = eB[201]; + t[12] = eB[202]; + t[13] = eB[204]; + + eB[155] = eB[142]; + eB[158] = eB[144]; + eB[161] = eB[145]; + eB[164] = eB[147]; + eB[167] = eB[148]; + eB[170] = eB[150]; + eB[173] = eB[151]; + eB[195] = eB[176]; + eB[196] = eB[179]; + eB[198] = eB[182]; + eB[199] = eB[185]; + eB[201] = eB[188]; + eB[202] = eB[191]; + eB[204] = eB[194]; + + eB[142] = t[0]; + eB[144] = t[1]; + eB[145] = t[2]; + eB[147] = t[3]; + eB[148] = t[4]; + eB[150] = t[5]; + eB[151] = t[6]; + eB[176] = t[7]; + eB[179] = t[8]; + eB[182] = t[9]; + eB[185] = t[10]; + eB[188] = t[11]; + eB[191] = t[12]; + eB[194] = t[13]; +} diff --git a/src/gsm/gsm0503_parity.c b/src/gsm/gsm0503_parity.c new file mode 100644 index 0000000..82183b5 --- /dev/null +++ b/src/gsm/gsm0503_parity.c @@ -0,0 +1,132 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +/* + * GSM (SACCH) parity (FIRE code) + * + * g(x) = (x^23 + 1)(x^17 + x^3 + 1) + * = x^40 + x^26 + x^23 + x^17 + x^3 + a1 + */ +const struct osmo_crc64gen_code gsm0503_fire_crc40 = { + .bits = 40, + .poly = 0x0004820009ULL, + .init = 0x0000000000ULL, + .remainder = 0xffffffffffULL, +}; + +/* + * GSM PDTCH CS-2, CS-3, CS-4 parity + * + * g(x) = x^16 + x^12 + x^5 + 1 + */ +const struct osmo_crc16gen_code gsm0503_cs234_crc16 = { + .bits = 16, + .poly = 0x1021, + .init = 0x0000, + .remainder = 0xffff, +}; + +/* + * EDGE MCS header parity + * + */ +const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = { + .bits = 8, + .poly = 0x49, + .init = 0x00, + .remainder = 0xff, +}; + +/* + * EDGE MCS data parity + * + */ +const struct osmo_crc16gen_code gsm0503_mcs_crc12 = { + .bits = 12, + .poly = 0x0d31, + .init = 0x0000, + .remainder = 0x0fff, +}; + +/* + * GSM RACH parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ +const struct osmo_crc8gen_code gsm0503_rach_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; + +/* + * GSM SCH parity + * + * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1 + */ +const struct osmo_crc16gen_code gsm0503_sch_crc10 = { + .bits = 10, + .poly = 0x175, + .init = 0x000, + .remainder = 0x3ff, +}; + +/* + * GSM TCH FR/HR/EFR parity + * + * g(x) = x^3 + x + 1 + */ +const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = { + .bits = 3, + .poly = 0x3, + .init = 0x0, + .remainder = 0x7, +}; + +/* + * GSM TCH EFR parity + * + * g(x) = x^8 + x^4 + x^3 + x^2 + 1 + */ +const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = { + .bits = 8, + .poly = 0x1d, + .init = 0x00, + .remainder = 0x00, +}; + +/* + * GSM AMR parity + * + * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1 + */ +const struct osmo_crc8gen_code gsm0503_amr_crc6 = { + .bits = 6, + .poly = 0x2f, + .init = 0x00, + .remainder = 0x3f, +}; diff --git a/src/gsm/gsm0503_tables.c b/src/gsm/gsm0503_tables.c new file mode 100644 index 0000000..883e212 --- /dev/null +++ b/src/gsm/gsm0503_tables.c @@ -0,0 +1,1732 @@ +/* + * (C) 2013 by Andreas Eversberg + * (C) 2016 by Tom Tsou + * + * All Rights Reserved + * + * 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 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 . + * + */ + +#include + +#include +#include + +const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = { + { 1,1, 1,1, 1,1, 1,1 }, + { 1,1, 0,0, 1,0, 0,0 }, + { 0,0, 1,0, 0,0, 0,1 }, + { 0,0, 0,1, 0,1, 1,0 }, +}; + +const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = { + { 0,0, 0,1, 0,1, 1,0 }, + { 0,0, 0,0, 0,0, 0,0 }, + { 1,1, 1,0, 0,1, 1,1 }, +}; + +const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = { + { -127,-127, -127,-127, -127,-127, -127,-127 }, + { -127,-127, 127, 127, -127, 127, 127, 127 }, + { 127, 127, -127, 127, 127, 127, 127,-127 }, + { 127, 127, 127,-127, 127,-127, -127, 127 }, +}; + +const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = { + { 127, 127, 127,-127, 127,-127, -127, 127 }, + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, -127, 127, 127,-127, -127,-127 }, +}; + +const ubit_t gsm0503_usf2six[8][6] = { + { 0,0,0, 0,0,0 }, + { 1,0,0, 1,0,1 }, + { 0,1,0, 1,1,0 }, + { 1,1,0, 0,1,1 }, + { 0,0,1, 0,1,1 }, + { 1,0,1, 1,1,0 }, + { 0,1,1, 1,0,1 }, + { 1,1,1, 0,0,0 }, +}; + +const ubit_t gsm0503_usf2twelve_ubit[8][12] = { + { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }, + { 1,1,0, 1,0,0, 0,0,1, 0,1,1 }, + { 0,0,1, 1,0,1, 1,1,0, 1,1,0 }, + { 1,1,1, 0,0,1, 1,1,1, 1,0,1 }, + { 0,0,0, 0,1,1, 0,1,1, 1,0,1 }, + { 1,1,0, 1,1,1, 0,1,0, 1,1,0 }, + { 0,0,1, 1,1,0, 1,0,1, 0,1,1 }, + { 1,1,1, 0,1,0, 1,0,0, 0,0,0 }, +}; + +const sbit_t gsm0503_usf2twelve_sbit[8][12] = { + { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }, + { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 }, + { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 }, + { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 }, + { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 }, + { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 }, + { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 }, + { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 }, +}; + +const uint8_t gsm0503_puncture_cs2[588] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, + 0,0,0,1, 0,0,0,1, 0,0,0,1 +}; + +const uint8_t gsm0503_puncture_cs3[676] = { + 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, + 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0 +}; + +const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = { + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,0,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p1[588] = { + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, + 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs1_p2[588] = { + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, + 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p1[732] = { + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, + 0,0,1,1,1,0, 0,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs2_p2[732] = { + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, + 1,1,0,0,0,1, 1,1,0,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p1[948] = { + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0, + 0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p2[948] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs3_p3[948] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs4_p1[1116] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p2[1116] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs4_p3[1116] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs5_p1[1404] = { + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs5_p2[1404] = { + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs6_p1[1836] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, + 0,0,1, 0,0,1, +}; + +const uint8_t gsm0503_puncture_mcs6_p2[1836] = { + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, + 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, + 0,1,0, 0,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0, + 0,1,0,0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p1[1404] = { + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, + 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs7_p2[1404] = { + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, + 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs7_p3[1404] = { + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, + 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p1[1692] = { + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, + 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0, +}; + +const uint8_t gsm0503_puncture_mcs8_p2[1692] = { + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, + 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs8_p3[1692] = { + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, + 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p1[1836] = { + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, + 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p2[1836] = { + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, + 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, +}; + +const uint8_t gsm0503_puncture_mcs9_p3[1836] = { + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, + 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, +}; + +const uint16_t gsm0503_interleave_mcs5[1248] = { + 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428, + 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968, + 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575, + 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688, + 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440, + 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980, + 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942, + 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700, + 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452, + 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414, + 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954, + 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712, + 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101, + 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420, + 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960, + 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567, + 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695, + 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432, + 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972, + 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937, + 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707, + 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444, + 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409, + 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949, + 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719, + 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096, + 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427, + 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967, + 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574, + 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687, + 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439, + 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979, + 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944, + 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699, + 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451, + 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416, + 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956, + 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711, + 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103, + 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422, + 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962, + 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569, + 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694, + 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434, + 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974, + 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936, + 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706, + 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446, + 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408, + 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948, + 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718, + 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095, + 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426, + 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966, + 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573, + 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689, + 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438, + 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978, + 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943, + 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701, + 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450, + 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415, + 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955, + 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713, + 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102, + 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421, + 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961, + 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568, + 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693, + 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433, + 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973, + 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938, + 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705, + 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445, + 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410, + 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950, + 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717, + 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097, +}; + +/* this corresponds to the bit-lengths of the individual codec + * parameters as indicated in Table 1.1 of TS 06.10 */ +const uint8_t gsm0503_gsm_fr_map[76] = { + 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* this table describes the 65 most importaint bits from EFR coded + * bits as indicated in TS 05.03 (3.1.1.1) */ +const uint8_t gsm0503_gsm_efr_protected_bits[65] = { + 39, 40, 41, 42, 43, 44, 48, 87, 45, 2, + 3, 8, 10, 18, 19, 24, 46, 47,142,143, + 144,145,146,147, 92, 93,195,196, 98,137, + 148, 94,197,149,150, 95,198, 4, 5, 11, + 12, 16, 9, 6, 7, 13, 17, 20, 96,199, + 1, 14, 15, 21, 25, 26, 28,151,201,190, + 240, 88,138,191,241 +}; + +/* Encoded in-band data for speech frames */ +const ubit_t gsm0503_afs_ic_ubit[4][8] = { + { 0,0,0,0,0,0,0,0 }, + { 0,1,0,1,1,1,0,1 }, + { 1,0,1,1,1,0,1,0 }, + { 1,1,1,0,0,1,1,1 }, +}; + +const sbit_t gsm0503_afs_ic_sbit[4][8] = { + { 127, 127, 127, 127, 127, 127, 127, 127 }, + { 127,-127, 127,-127,-127,-127, 127,-127 }, + { -127, 127,-127,-127,-127, 127,-127, 127 }, + { -127,-127,-127, 127, 127,-127,-127,-127 }, +}; + +const ubit_t gsm0503_ahs_ic_ubit[4][4] = { + { 0,0,0,0 }, + { 1,0,0,1 }, + { 1,1,1,0 }, + { 0,1,1,1 }, +}; + +const sbit_t gsm0503_ahs_ic_sbit[4][4] = { + { 127, 127, 127, 127 }, + { -127, 127, 127,-127 }, + { -127,-127,-127, 127 }, + { 127,-127,-127,-127 }, +}; + +const uint8_t gsm0503_tch_hr_interleaving[228][2] = { + { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 }, + { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 }, + { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 }, + { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 }, + { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 }, + { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 }, + { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 }, + { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 }, + { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 }, + { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 }, + { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 }, + { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 }, + { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 }, + { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 }, + { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 }, + { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 }, + { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 }, + { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 }, + { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 }, + { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 }, + { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 }, + { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 }, + { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 }, + { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 }, + { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 }, + { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 }, + { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 }, + { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 }, + { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 }, + { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 }, + { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 }, + { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 }, + { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 }, + { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 }, + { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 }, + { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 }, + { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 }, + { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 }, +}; + +/* + * 3GPP TS 05.03 5.1.9.1.2 "USF precoding" + */ +const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = { + { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, }, + { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, }, + { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, }, + { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, }, + { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, }, + { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, }, + { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, }, + { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, }, +}; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index a83f92c..28d902a 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -107,6 +107,118 @@ gsm0503_mcs8; gsm0503_mcs9; +gsm0503_pdtch_hl_hn_ubit; +gsm0503_pdtch_edge_hl_hn_ubit; +gsm0503_pdtch_hl_hn_sbit; +gsm0503_pdtch_edge_hl_hn_sbit; +gsm0503_usf2six; +gsm0503_usf2twelve_ubit; +gsm0503_usf2twelve_sbit; +gsm0503_puncture_cs2; +gsm0503_puncture_cs3; +gsm0503_puncture_mcs1_dl_hdr; +gsm0503_puncture_mcs1_ul_hdr; +gsm0503_puncture_mcs1_p1; +gsm0503_puncture_mcs1_p2; +gsm0503_puncture_mcs2_p1; +gsm0503_puncture_mcs2_p2; +gsm0503_puncture_mcs3_p1; +gsm0503_puncture_mcs3_p2; +gsm0503_puncture_mcs3_p3; +gsm0503_puncture_mcs4_p1; +gsm0503_puncture_mcs4_p2; +gsm0503_puncture_mcs4_p3; +gsm0503_puncture_mcs5_p1; +gsm0503_puncture_mcs5_p2; +gsm0503_puncture_mcs6_p1; +gsm0503_puncture_mcs6_p2; +gsm0503_puncture_mcs7_dl_hdr; +gsm0503_puncture_mcs7_ul_hdr; +gsm0503_puncture_mcs7_p1; +gsm0503_puncture_mcs7_p2; +gsm0503_puncture_mcs7_p3; +gsm0503_puncture_mcs8_p1; +gsm0503_puncture_mcs8_p2; +gsm0503_puncture_mcs8_p3; +gsm0503_puncture_mcs9_p1; +gsm0503_puncture_mcs9_p2; +gsm0503_puncture_mcs9_p3; +gsm0503_interleave_mcs5; +gsm0503_gsm_fr_map; +gsm0503_gsm_efr_protected_bits; +gsm0503_afs_ic_ubit; +gsm0503_afs_ic_sbit; +gsm0503_ahs_ic_ubit; +gsm0503_ahs_ic_sbit; +gsm0503_tch_hr_interleaving; +gsm0503_mcs5_usf_precode_table; + +gsm0503_fire_crc40; +gsm0503_cs234_crc16; +gsm0503_mcs_crc8_hdr; +gsm0503_mcs_crc12; +gsm0503_rach_crc6; +gsm0503_sch_crc10; +gsm0503_tch_fr_crc3; +gsm0503_tch_efr_crc8; +gsm0503_amr_crc6; + +gsm0503_xcch_burst_unmap; +gsm0503_xcch_burst_map; +gsm0503_tch_burst_unmap; +gsm0503_tch_burst_map; +gsm0503_mcs5_ul_burst_map; +gsm0503_mcs5_ul_burst_unmap; +gsm0503_mcs7_ul_burst_map; +gsm0503_mcs7_ul_burst_unmap; +gsm0503_mcs5_dl_burst_map; +gsm0503_mcs5_dl_burst_unmap; +gsm0503_mcs7_dl_burst_map; +gsm0503_mcs7_dl_burst_unmap; +gsm0503_mcs5_burst_swap; + +gsm0503_xcch_deinterleave; +gsm0503_xcch_interleave; +gsm0503_tch_fr_deinterleave; +gsm0503_tch_fr_interleave; +gsm0503_tch_hr_deinterleave; +gsm0503_tch_hr_interleave; +gsm0503_mcs1_ul_deinterleave; +gsm0503_mcs1_ul_interleave; +gsm0503_mcs1_dl_deinterleave; +gsm0503_mcs1_dl_interleave; +gsm0503_mcs5_ul_deinterleave; +gsm0503_mcs5_ul_interleave; +gsm0503_mcs5_dl_deinterleave; +gsm0503_mcs5_dl_interleave; +gsm0503_mcs7_ul_deinterleave; +gsm0503_mcs7_ul_interleave; +gsm0503_mcs7_dl_deinterleave; +gsm0503_mcs7_dl_interleave; +gsm0503_mcs8_ul_deinterleave; +gsm0503_mcs8_ul_interleave; +gsm0503_mcs8_dl_deinterleave; +gsm0503_mcs8_dl_interleave; + +gsm0503_xcch_encode; +gsm0503_xcch_decode; +gsm0503_pdtch_encode; +gsm0503_pdtch_decode; +gsm0503_pdtch_egprs_encode; +gsm0503_pdtch_egprs_decode; +gsm0503_tch_fr_encode; +gsm0503_tch_fr_decode; +gsm0503_tch_hr_encode; +gsm0503_tch_hr_decode; +gsm0503_tch_afs_encode; +gsm0503_tch_afs_decode; +gsm0503_tch_ahs_encode; +gsm0503_tch_ahs_decode; +gsm0503_rach_encode; +gsm0503_rach_decode; +gsm0503_sch_encode; +gsm0503_sch_decode; + gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Fri Sep 9 09:56:37 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 09:56:37 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/828 to look at the new patch set (#2). utils/conv_gen.py: generate a single file Instead of generating every convolutional code into a separate file (such as conv_xcch_gen.c, conv_cs3_gen.c), it is better to have a single file, containing all the tables, because more tables is more files. Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa --- M .gitignore M src/gsm/Makefile.am M utils/conv_gen.py 3 files changed, 309 insertions(+), 316 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/828/2 diff --git a/.gitignore b/.gitignore index 5165364..90c8c85 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,7 @@ doc/*.tag src/crc*gen.c -src/gsm/conv*gen.c +src/gsm/gsm0503_conv.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..9a9d96f 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,11 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c + gsup.c gprs_gea.c gsm0503_conv.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +32,6 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py - $(AM_V_GEN)python2 ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: + $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py diff --git a/utils/conv_gen.py b/utils/conv_gen.py index a4f918f..38ea63b 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -222,325 +222,322 @@ ( G1, 1 ), ] -# xCCH definition -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description = [ - "xCCH convolutional code:", - "228 bits blocks, rate 1/2, k = 5", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS2 definition -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description = [ - "CS2 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS3 definition -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description = [ - "CS3 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# TCH_AFS_12_2 definition -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = [ - "TCH/AFS 12.2 kbits convolutional code:", - "250 bits block, rate 1/2, punctured", - "G0/G0 = 1", - "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", - ] -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -# TCH_AFS_10_2 definition -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = [ - "TCH/AFS 10.2 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_7_95 definition -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = [ - "TCH/AFS 7.95 kbits convolutional code:", - "G4/G4 = 1", - "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", - "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", - ] -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -# TCH_AFS_7_4 definition -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = [ - "TCH/AFS 7.4 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_6_7 definition -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = [ - "TCH/AFS 6.7 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_5_9 definition -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = [ - "TCH/AFS 5.9 kbits convolutional code:", - "124 bits", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -# TCH_AFS_5_15 definition -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = [ - "TCH/AFS 5.15 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_4_75 definition -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = [ - "TCH/AFS 4.75 kbits convolutional code:", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ) +] -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Fri Sep 9 10:02:24 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 10:02:24 +0000 Subject: libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Patch Set 1: > > Please be more verbose in the commit message. A single file of > > what? Which files are now merged into which other file? > > No problem, I will extend the commit message. Done. -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 10:10:13 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 10:10:13 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: improve output formatting In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/829 to look at the new patch set (#2). utils/conv_gen.py: improve output formatting To keep the generated tables readable, line with should be limited. So, now there are the following limitations: - _print_term(): up to 12 numbers per line, - _print_puncture(): up to 12 numbers per line, - _print_x(): up to 4 blocks per line. Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c --- M src/gsm/Makefile.am M utils/conv_gen.py 2 files changed, 43 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/29/829/2 diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 9a9d96f..d367c89 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -35,3 +35,5 @@ # Convolutional codes generation gsm0503_conv.c: $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py + +CLEANFILES = gsm0503_conv.c diff --git a/utils/conv_gen.py b/utils/conv_gen.py index 38ea63b..5a519bc 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -129,17 +129,30 @@ return ns, nb def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): if pack: x = pack(self.next_term_output(state)) else: x = self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): if pack: x0 = pack(self.next_output(state, 0)) @@ -148,7 +161,30 @@ x0 = self.next_state(state, 0) x1 = self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") + + def _print_puncture(self, fi): + # Up to 12 numbers should be placed per line + counter = 0 + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): pack = lambda n: \ @@ -173,10 +209,10 @@ self._print_term(fi, num_states, pack) print >>fi, "};" + # Write puncture if preset if len(self.puncture): print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p + self._print_puncture(fi) print >>fi, "};" # Write description as a multi-line comment -- To view, visit https://gerrit.osmocom.org/829 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 10:16:50 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 10:16:50 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions In-Reply-To: References: Message-ID: Patch Set 1: > the question to me is, both regarding the existing GSM coding > schemes and the new EGPRS MCS: Where are the test cases? > > We should be able to do a pretty simple Encode -> Decode test to > test against our own encoder, and have that test be executed with > every of the convolutional codes. We should also be able to > introduce a defined amount of bit errors and check if the decoder > can still recover as expected (won't work for MCS-9/CS-4, of > course). > > We should also test decoding of some hardcoded 'const uint8_t' > arrays of actual messages produced by a different encoder (e.g from > air interface traces). > the question to me is, both regarding the existing GSM coding > schemes and the new EGPRS MCS: Where are the test cases? > > We should be able to do a pretty simple Encode -> Decode test to > test against our own encoder, and have that test be executed with > every of the convolutional codes. We should also be able to > introduce a defined amount of bit errors and check if the decoder > can still recover as expected (won't work for MCS-9/CS-4, of > course). > > We should also test decoding of some hardcoded 'const uint8_t' > arrays of actual messages produced by a different encoder (e.g from > air interface traces). I am absolutely agree with you, but right now I have no opportunity to write corresponding tests. Also, I have no corresponding air interface traces at this moment. But I will try to solve this problem. Can we add tests in a separate commit? -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 9 10:22:23 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 9 Sep 2016 10:22:23 +0000 Subject: [ABANDON] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Fri Sep 9 14:24:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 14:24:06 +0000 Subject: [PATCH] libosmocore[master]: comment: */ports.h: link to wiki + manuals, indicate used ports In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/833 to look at the new patch set (#2). comment: */ports.h: link to wiki + manuals, indicate used ports Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 16 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/833/2 diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index c89bbe3..9642193 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -1,10 +1,18 @@ #pragma once -/* TCP port numbers used for CTRL interfaces in osmocom projects */ +/* + * TCP port numbers used for CTRL interfaces in osmocom projects. See also the + * osmocom wiki as well as the osmo-gsm-manuals, which should all be kept in + * sync with this file: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers + * https://git.osmocom.org/osmo-gsm-manuals/tree/common/chapters/port_numbers.adoc + */ #define OSMO_CTRL_PORT_BTS 4238 #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 #define OSMO_CTRL_PORT_GGSN 4252 +/* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 +/* 4256 used by VTY interface */ diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 75b8044..b135515 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -1,6 +1,12 @@ #pragma once -/* TCP port numbers used for VTY interfaces in osmocom projects */ +/* + * TCP port numbers used for VTY interfaces in osmocom projects. See also the + * osmocom wiki as well as the osmo-gsm-manuals, which should all be kept in + * sync with this file: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers + * https://git.osmocom.org/osmo-gsm-manuals/tree/common/chapters/port_numbers.adoc + */ /* 4238 used by osmo-bts control interface */ #define OSMO_VTY_PORT_PCU 4240 /* also: osmo_pcap_client */ -- To view, visit https://gerrit.osmocom.org/833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 14:24:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 14:24:06 +0000 Subject: [PATCH] libosmocore[master]: fix GGSN Ctrl port to 4257 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/834 to look at the new patch set (#2). fix GGSN Ctrl port to 4257 4253 used to collide with the sysmobts-mgr VTY port. Note, openggsn does not actually have a Ctrl interface yet. Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/34/834/2 diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index 9642193..8bd8680 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -12,7 +12,7 @@ #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 -#define OSMO_CTRL_PORT_GGSN 4252 /* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 /* 4256 used by VTY interface */ +#define OSMO_CTRL_PORT_GGSN 4257 diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index b135515..c5e396b 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -23,3 +23,4 @@ #define OSMO_VTY_PORT_CSCN 4254 /* 4255 used by control interface */ #define OSMO_VTY_PORT_MNCC_SIP 4256 +/* 4257 used by control interface */ -- To view, visit https://gerrit.osmocom.org/834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 9 14:46:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 9 Sep 2016 14:46:48 +0000 Subject: [PATCH] libosmocore[master]: build: tests: don't link system installed libosmogsm. Message-ID: Review at https://gerrit.osmocom.org/842 build: tests: don't link system installed libosmogsm. Add src/gsm/libosmogsm.la explicitly to some test linkages, because otherwise the linker would pick the libosmogsm already installed on the system instead of the one that was just built in the source tree. I noticed because a libosmogsm needing some more symbols from libosmocodec was still installed, while the patch that cause it was already removed. Thus I caught all(?) test binaries that linked libosmogsm from $PREFIX. Change-Id: Ie61d60e1506f16de20add70fd0f44ebfa7a00a75 --- M tests/Makefile.am 1 file changed, 10 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/42/842/1 diff --git a/tests/Makefile.am b/tests/Makefile.am index 9b85e6d..ae5735a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -86,19 +86,23 @@ ussd_ussd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la gb_bssgp_fc_test_SOURCES = gb/bssgp_fc_test.c -gb_bssgp_fc_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la +gb_bssgp_fc_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la \ + $(top_builddir)/src/gsm/libosmogsm.la gb_gprs_bssgp_test_SOURCES = gb/gprs_bssgp_test.c -gb_gprs_bssgp_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +gb_gprs_bssgp_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c -gb_gprs_ns_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +gb_gprs_ns_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la logging_logging_test_SOURCES = logging/logging_test.c logging_logging_test_LDADD = $(top_builddir)/src/libosmocore.la fr_fr_test_SOURCES = fr/fr_test.c -fr_fr_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +fr_fr_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la codec_codec_test_SOURCES = codec/codec_test.c codec_codec_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/codec/libosmocodec.la @@ -113,7 +117,8 @@ vty_vty_test_LDADD = $(top_builddir)/src/vty/libosmovty.la $(top_builddir)/src/libosmocore.la sim_sim_test_SOURCES = sim/sim_test.c -sim_sim_test_LDADD = $(top_builddir)/src/sim/libosmosim.la $(top_builddir)/src/libosmocore.la +sim_sim_test_LDADD = $(top_builddir)/src/sim/libosmosim.la $(top_builddir)/src/libosmocore.la \ + $(top_builddir)/src/gsm/libosmogsm.la tlv_tlv_test_SOURCES = tlv/tlv_test.c tlv_tlv_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la -- To view, visit https://gerrit.osmocom.org/842 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie61d60e1506f16de20add70fd0f44ebfa7a00a75 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:02:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:02:49 +0000 Subject: libosmocore[master]: comment: */ports.h: link to wiki + manuals, indicate used ports In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:02:55 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:02:55 +0000 Subject: [MERGED] libosmocore[master]: comment: */ports.h: link to wiki + manuals, indicate used ports In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: comment: */ports.h: link to wiki + manuals, indicate used ports ...................................................................... comment: */ports.h: link to wiki + manuals, indicate used ports Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 16 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index c89bbe3..9642193 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -1,10 +1,18 @@ #pragma once -/* TCP port numbers used for CTRL interfaces in osmocom projects */ +/* + * TCP port numbers used for CTRL interfaces in osmocom projects. See also the + * osmocom wiki as well as the osmo-gsm-manuals, which should all be kept in + * sync with this file: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers + * https://git.osmocom.org/osmo-gsm-manuals/tree/common/chapters/port_numbers.adoc + */ #define OSMO_CTRL_PORT_BTS 4238 #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 #define OSMO_CTRL_PORT_GGSN 4252 +/* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 +/* 4256 used by VTY interface */ diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 75b8044..b135515 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -1,6 +1,12 @@ #pragma once -/* TCP port numbers used for VTY interfaces in osmocom projects */ +/* + * TCP port numbers used for VTY interfaces in osmocom projects. See also the + * osmocom wiki as well as the osmo-gsm-manuals, which should all be kept in + * sync with this file: + * https://osmocom.org/projects/cellular-infrastructure/wiki/PortNumbers + * https://git.osmocom.org/osmo-gsm-manuals/tree/common/chapters/port_numbers.adoc + */ /* 4238 used by osmo-bts control interface */ #define OSMO_VTY_PORT_PCU 4240 /* also: osmo_pcap_client */ -- To view, visit https://gerrit.osmocom.org/833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6a7bf04e589ccfaea98f20900a9bfe9dd4808dce Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:03:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:03:06 +0000 Subject: libosmocore[master]: fix GGSN Ctrl port to 4257 In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:03:09 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:03:09 +0000 Subject: [MERGED] libosmocore[master]: fix GGSN Ctrl port to 4257 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: fix GGSN Ctrl port to 4257 ...................................................................... fix GGSN Ctrl port to 4257 4253 used to collide with the sysmobts-mgr VTY port. Note, openggsn does not actually have a Ctrl interface yet. Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 --- M include/osmocom/ctrl/ports.h M include/osmocom/vty/ports.h 2 files changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/ports.h b/include/osmocom/ctrl/ports.h index 9642193..8bd8680 100644 --- a/include/osmocom/ctrl/ports.h +++ b/include/osmocom/ctrl/ports.h @@ -12,7 +12,7 @@ #define OSMO_CTRL_PORT_NITB_BSC 4249 #define OSMO_CTRL_PORT_BSC_NAT 4250 #define OSMO_CTRL_PORT_SGSN 4251 -#define OSMO_CTRL_PORT_GGSN 4252 /* 4252-4254 used by VTY interface */ #define OSMO_CTRL_PORT_CSCN 4255 /* 4256 used by VTY interface */ +#define OSMO_CTRL_PORT_GGSN 4257 diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index b135515..c5e396b 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -23,3 +23,4 @@ #define OSMO_VTY_PORT_CSCN 4254 /* 4255 used by control interface */ #define OSMO_VTY_PORT_MNCC_SIP 4256 +/* 4257 used by control interface */ -- To view, visit https://gerrit.osmocom.org/834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If0fa0e606dabd5bc89907a56ef18cdbbbdedb4b7 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:03:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:03:34 +0000 Subject: libosmocore[master]: build: tests: don't link system installed libosmogsm. In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/842 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie61d60e1506f16de20add70fd0f44ebfa7a00a75 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:03:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:03:39 +0000 Subject: [MERGED] libosmocore[master]: build: tests: don't link system installed libosmogsm. In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: build: tests: don't link system installed libosmogsm. ...................................................................... build: tests: don't link system installed libosmogsm. Add src/gsm/libosmogsm.la explicitly to some test linkages, because otherwise the linker would pick the libosmogsm already installed on the system instead of the one that was just built in the source tree. I noticed because a libosmogsm needing some more symbols from libosmocodec was still installed, while the patch that cause it was already removed. Thus I caught all(?) test binaries that linked libosmogsm from $PREFIX. Change-Id: Ie61d60e1506f16de20add70fd0f44ebfa7a00a75 --- M tests/Makefile.am 1 file changed, 10 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/Makefile.am b/tests/Makefile.am index 9b85e6d..ae5735a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -86,19 +86,23 @@ ussd_ussd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la gb_bssgp_fc_test_SOURCES = gb/bssgp_fc_test.c -gb_bssgp_fc_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la +gb_bssgp_fc_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la \ + $(top_builddir)/src/gsm/libosmogsm.la gb_gprs_bssgp_test_SOURCES = gb/gprs_bssgp_test.c -gb_gprs_bssgp_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +gb_gprs_bssgp_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c -gb_gprs_ns_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +gb_gprs_ns_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la logging_logging_test_SOURCES = logging/logging_test.c logging_logging_test_LDADD = $(top_builddir)/src/libosmocore.la fr_fr_test_SOURCES = fr/fr_test.c -fr_fr_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) +fr_fr_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \ + $(top_builddir)/src/gsm/libosmogsm.la codec_codec_test_SOURCES = codec/codec_test.c codec_codec_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/codec/libosmocodec.la @@ -113,7 +117,8 @@ vty_vty_test_LDADD = $(top_builddir)/src/vty/libosmovty.la $(top_builddir)/src/libosmocore.la sim_sim_test_SOURCES = sim/sim_test.c -sim_sim_test_LDADD = $(top_builddir)/src/sim/libosmosim.la $(top_builddir)/src/libosmocore.la +sim_sim_test_LDADD = $(top_builddir)/src/sim/libosmosim.la $(top_builddir)/src/libosmocore.la \ + $(top_builddir)/src/gsm/libosmogsm.la tlv_tlv_test_SOURCES = tlv/tlv_test.c tlv_tlv_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la -- To view, visit https://gerrit.osmocom.org/842 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie61d60e1506f16de20add70fd0f44ebfa7a00a75 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:04:05 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:04:05 +0000 Subject: libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:04:11 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:04:11 +0000 Subject: libosmocore[master]: utils/conv_gen.py: code style changes (line width, tabs, etc.) In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/827 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:04:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:04:52 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 10 12:06:53 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 10 Sep 2016 12:06:53 +0000 Subject: libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 (1 comment) https://gerrit.osmocom.org/#/c/841/1/src/gsm/gsm0503_coding.c File src/gsm/gsm0503_coding.c: PS1, Line 9: Affero General Public License we have a licensing conflict here. The routines appear to be licensed under AGPLv3+, but libosmocore code is GPLv2+. We'd want to keep the library GPLv2+, and permit non-AGPL users. What would need to be done is to contact all authors/copyright holders of the existing code and ask them if they agree to a re-licensing under GPLv2-or-later. -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 10 13:45:42 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 10 Sep 2016 13:45:42 +0000 Subject: libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/841/1/src/gsm/gsm0503_coding.c File src/gsm/gsm0503_coding.c: PS1, Line 9: Affero General Public License > we have a licensing conflict here. The routines appear to be licensed unde Sorry, I didn't paid my attention... Well, let's do it! I will try to contact all authors/copyright holders. But I am not sure, will Andreas answer me or not. I wrote him a mail in the past, but he didn't respond me. Could you help me with this? -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 12 06:13:48 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 06:13:48 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Patch Set 1: Hi All, Any updates on this patch set? Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 06:14:13 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 06:14:13 +0000 Subject: osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... In-Reply-To: References: Message-ID: Patch Set 1: Hi All, Any updates on this patch set? Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 06:21:12 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 06:21:12 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: Hi Neels, Any updates on this patch series? Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 07:24:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 07:24:40 +0000 Subject: [PATCH] osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/832 to look at the new patch set (#2). Refactoring: New function to calculate EGPRS DL window size Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h 2 files changed, 25 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/2 diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..edd94ae 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->calc_egprs_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); @@ -1247,3 +1235,23 @@ { return ts == control_ts; } + +void gprs_rlcmac_dl_tbf::calc_egprs_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3c92768 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,9 @@ int release(); int abort(); + /* EGPRS: window size calculation function */ + void calc_egprs_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 12 07:24:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 07:24:40 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#4). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 9 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/4 diff --git a/src/tbf.cpp b/src/tbf.cpp index edd94ae..cda3495 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,11 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + dl_tbf->calc_egprs_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..ea6dcdd 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..d5e8cfa 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Mon Sep 12 07:24:41 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 07:24:41 +0000 Subject: [PATCH] osmo-pcu[master]: TBF flow: unit test compilation error fix Message-ID: Review at https://gerrit.osmocom.org/843 TBF flow: unit test compilation error fix Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 --- M tests/tbf/TbfTest.err 1 file changed, 39 insertions(+), 35 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/43/843/1 diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a905b1b..a83353c 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -601,7 +601,7 @@ TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -628,7 +628,7 @@ TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 03 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -655,7 +655,7 @@ TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 03 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -682,7 +682,7 @@ TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 03 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -709,7 +709,7 @@ TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 03 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -736,7 +736,7 @@ TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 03 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -763,7 +763,7 @@ TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 03 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -790,7 +790,7 @@ TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 03 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -817,7 +817,7 @@ TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 03 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -844,7 +844,7 @@ TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 03 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -871,7 +871,7 @@ TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 03 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -898,7 +898,7 @@ TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 03 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -925,7 +925,7 @@ TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 03 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -952,7 +952,7 @@ TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 03 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -979,7 +979,7 @@ TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 03 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1006,7 +1006,7 @@ TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 03 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1033,7 +1033,7 @@ TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 03 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1060,7 +1060,7 @@ TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 03 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1087,7 +1087,7 @@ TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 03 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1114,7 +1114,7 @@ TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 03 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1141,7 +1141,7 @@ TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 03 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1168,7 +1168,7 @@ TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 03 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1195,7 +1195,7 @@ TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 03 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1222,7 +1222,7 @@ TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 03 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1249,7 +1249,7 @@ TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 03 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1276,7 +1276,7 @@ TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 03 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1303,7 +1303,7 @@ TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 03 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1330,7 +1330,7 @@ TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 03 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1357,7 +1357,7 @@ TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 03 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1384,7 +1384,7 @@ TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 03 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1411,7 +1411,7 @@ TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 03 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1438,7 +1438,7 @@ TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 03 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1473,7 +1473,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append Modifying MS object, TLLI = 0xc0123456, TA 220 -> 0 @@ -3511,7 +3511,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) @@ -6026,6 +6026,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6082,6 +6083,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6138,6 +6140,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6194,6 +6197,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6270,7 +6274,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) -- To view, visit https://gerrit.osmocom.org/843 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Mon Sep 12 07:26:23 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 07:26:23 +0000 Subject: osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Patch Set 2: (2 comments) https://gerrit.osmocom.org/#/c/832/1/src/tbf.cpp File src/tbf.cpp: Line 1253: LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", > (technically, you added an indent here) Fixed in latest series. Line 1255: > After figuring out window() and the 'direction' member, The function is moved to gprs_rlcmac_dl_tbf class. -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 12 07:45:57 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 12 Sep 2016 07:45:57 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 4: Hi Neels/Holger, I have updated the patch series as per your recommendation. Since current UT framework is getting failed to run. I have uploaded the base patch to fix UT first. On top of that I have submitted 2 patches related to window size for DL. Please have a look. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 12:57:12 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 12 Sep 2016 12:57:12 +0000 Subject: osmo-pcu[master]: TBF flow: unit test compilation error fix In-Reply-To: References: Message-ID: Patch Set 1: Looks good. Seems that Idfc40ff0c11bdac13d9e28fbfa4e95dfc6b735b0 was rebased and then submitted before it went through the CI. @Harald: Please verify the change, e.g. if TA is applied in the testcase. -- To view, visit https://gerrit.osmocom.org/843 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 13:21:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 12 Sep 2016 13:21:48 +0000 Subject: [PATCH] osmo-pcu[master]: TBF flow: unit test compilation error fix In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/843 to look at the new patch set (#2). TBF flow: unit test compilation error fix The test failure was introduced by 9bbe1600cc02e1b538380393edb1dcdabe9247a2 "Fix Timing Advance handling": between patch build checking and patch submission, a new section was added to TbfTest.cpp which also needs adjustment. Tweaked-by: Neels Hofmeyr Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 --- M tests/tbf/TbfTest.err 1 file changed, 39 insertions(+), 35 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/43/843/2 diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a905b1b..a83353c 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -601,7 +601,7 @@ TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -628,7 +628,7 @@ TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 03 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -655,7 +655,7 @@ TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 03 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -682,7 +682,7 @@ TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 03 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -709,7 +709,7 @@ TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 03 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -736,7 +736,7 @@ TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 03 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -763,7 +763,7 @@ TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 03 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -790,7 +790,7 @@ TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 03 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -817,7 +817,7 @@ TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 03 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -844,7 +844,7 @@ TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 03 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -871,7 +871,7 @@ TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 03 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -898,7 +898,7 @@ TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 03 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -925,7 +925,7 @@ TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 03 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -952,7 +952,7 @@ TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 03 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -979,7 +979,7 @@ TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 03 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1006,7 +1006,7 @@ TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 03 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1033,7 +1033,7 @@ TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 03 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1060,7 +1060,7 @@ TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 03 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1087,7 +1087,7 @@ TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 03 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1114,7 +1114,7 @@ TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 03 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1141,7 +1141,7 @@ TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 03 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1168,7 +1168,7 @@ TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 03 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1195,7 +1195,7 @@ TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 03 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1222,7 +1222,7 @@ TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 03 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1249,7 +1249,7 @@ TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 03 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1276,7 +1276,7 @@ TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 03 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1303,7 +1303,7 @@ TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 03 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1330,7 +1330,7 @@ TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 03 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1357,7 +1357,7 @@ TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 03 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1384,7 +1384,7 @@ TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 03 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1411,7 +1411,7 @@ TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 03 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1438,7 +1438,7 @@ TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 03 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1473,7 +1473,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append Modifying MS object, TLLI = 0xc0123456, TA 220 -> 0 @@ -3511,7 +3511,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) @@ -6026,6 +6026,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6082,6 +6083,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6138,6 +6140,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6194,6 +6197,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6270,7 +6274,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) -- To view, visit https://gerrit.osmocom.org/843 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 12 13:22:25 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 12 Sep 2016 13:22:25 +0000 Subject: osmo-pcu[master]: TBF flow: unit test compilation error fix In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 I tweaked the commit log to mention the cause of the build failure. -- To view, visit https://gerrit.osmocom.org/843 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 12 13:22:39 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 12 Sep 2016 13:22:39 +0000 Subject: [MERGED] osmo-pcu[master]: TBF flow: unit test compilation error fix In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: TBF flow: unit test compilation error fix ...................................................................... TBF flow: unit test compilation error fix The test failure was introduced by 9bbe1600cc02e1b538380393edb1dcdabe9247a2 "Fix Timing Advance handling": between patch build checking and patch submission, a new section was added to TbfTest.cpp which also needs adjustment. Tweaked-by: Neels Hofmeyr Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 --- M tests/tbf/TbfTest.err 1 file changed, 39 insertions(+), 35 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a905b1b..a83353c 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -601,7 +601,7 @@ TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -628,7 +628,7 @@ TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 03 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -655,7 +655,7 @@ TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 03 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -682,7 +682,7 @@ TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 03 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -709,7 +709,7 @@ TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 03 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -736,7 +736,7 @@ TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 03 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -763,7 +763,7 @@ TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 03 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -790,7 +790,7 @@ TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 03 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -817,7 +817,7 @@ TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 03 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -844,7 +844,7 @@ TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 03 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -871,7 +871,7 @@ TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 03 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -898,7 +898,7 @@ TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 03 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -925,7 +925,7 @@ TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 03 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -952,7 +952,7 @@ TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 03 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -979,7 +979,7 @@ TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 03 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1006,7 +1006,7 @@ TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 03 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1033,7 +1033,7 @@ TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 03 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1060,7 +1060,7 @@ TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 03 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1087,7 +1087,7 @@ TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 03 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1114,7 +1114,7 @@ TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 03 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1141,7 +1141,7 @@ TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 03 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1168,7 +1168,7 @@ TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 03 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1195,7 +1195,7 @@ TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 03 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1222,7 +1222,7 @@ TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 03 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1249,7 +1249,7 @@ TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 03 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1276,7 +1276,7 @@ TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 03 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1303,7 +1303,7 @@ TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 03 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1330,7 +1330,7 @@ TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 03 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1357,7 +1357,7 @@ TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 03 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1384,7 +1384,7 @@ TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 03 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1411,7 +1411,7 @@ TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 03 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1438,7 +1438,7 @@ TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 03 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** @@ -1473,7 +1473,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 -Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 23 2b 2b 2b 2b +Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 03 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append Modifying MS object, TLLI = 0xc0123456, TA 220 -> 0 @@ -3511,7 +3511,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) @@ -6026,6 +6026,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6082,6 +6083,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6138,6 +6140,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6194,6 +6197,7 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append @@ -6270,7 +6274,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed -Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 Change control TS to 7 until assinment is complete. max_cs_ul cannot be derived (current UL CS: UNKNOWN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) -- To view, visit https://gerrit.osmocom.org/843 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If077da5f21fd5cba54556f1dead05a1bc4ea5540 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 12 13:47:04 2016 From: gerrit-no-reply at lists.osmocom.org (lynxis lazus) Date: Mon, 12 Sep 2016 13:47:04 +0000 Subject: [PATCH] openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/551 to look at the new patch set (#5). sms: change rp err cause of smpp_try_deliver errors smpp_try_deliver could fail with rc < 0. In such cases don't send the MS the rp error sms rejected (cause 21). A rejected message should not be sent again. The spec 04 11 recommends sending cause 41 Temporary failure in unknown cases. Add also a log message and rate counter for such cases. Tweaked-By: Neels Hofmeyr Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libmsc/gsm_04_11.c 2 files changed, 15 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/51/551/5 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..40577cc 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -198,6 +198,7 @@ MSC_CTR_SMS_DELIVERED, MSC_CTR_SMS_RP_ERR_MEM, MSC_CTR_SMS_RP_ERR_OTHER, + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR, MSC_CTR_CALL_MO_SETUP, MSC_CTR_CALL_MO_CONNECT_ACK, MSC_CTR_CALL_MT_SETUP, @@ -216,6 +217,7 @@ [MSC_CTR_SMS_DELIVERED] = {"sms.delivered", "Global SMS Deliver attempts."}, [MSC_CTR_SMS_RP_ERR_MEM] = {"sms.rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."}, [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms.rp_err_other", "Other error of MS responses on a sms delive attempt."}, + [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "Unknown error during sms delivery occured."}, /* FIXME: count also sms delivered */ [MSC_CTR_CALL_MO_SETUP] = {"call.mo_setup", "Received setup requests from a MS to init a MO call."}, [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 6d3f41b..d1fdfb9 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -294,8 +295,12 @@ if (rc == 1) goto try_local; if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } return rc; } @@ -319,8 +324,12 @@ rc = 1; /* cause 1: unknown subscriber */ rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); } else if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } #else rc = 1; /* cause 1: unknown subscriber */ -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus From gerrit-no-reply at lists.osmocom.org Mon Sep 12 14:11:20 2016 From: gerrit-no-reply at lists.osmocom.org (lynxis lazus) Date: Mon, 12 Sep 2016 14:11:20 +0000 Subject: [PATCH] openbsc[master]: bsc: count the usage of codec by setting the lchan active In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/794 to look at the new patch set (#2). bsc: count the usage of codec by setting the lchan active we count the codec when the channel was successful setted up Change-Id: Ifc8a406a11dce16b9e7f3310841e470545550a2c --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/abis_rsl.c 2 files changed, 45 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/94/794/2 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 40577cc..040ff3e 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -166,6 +166,11 @@ BSC_CTR_CHAN_RLL_ERR, BSC_CTR_BTS_OML_FAIL, BSC_CTR_BTS_RSL_FAIL, + BSC_CTR_CODEC_AMR_F, + BSC_CTR_CODEC_AMR_H, + BSC_CTR_CODEC_EFR, + BSC_CTR_CODEC_V1_FR, + BSC_CTR_CODEC_V1_HR, }; static const struct rate_ctr_desc bsc_ctr_description[] = { @@ -184,6 +189,11 @@ [BSC_CTR_CHAN_RLL_ERR] = {"chan.rll_err", "Received a RLL failure with T200 cause from BTS."}, [BSC_CTR_BTS_OML_FAIL] = {"bts.oml_fail", "Received a TEI down on a OML link."}, [BSC_CTR_BTS_RSL_FAIL] = {"bts.rsl_fail", "Received a TEI down on a OML link."}, + [BSC_CTR_CODEC_AMR_F] = {"bts.codec_amr_f", "Count the usage of AMR/F codec by channel mode requested."}, + [BSC_CTR_CODEC_AMR_H] = {"bts.codec_amr_h", "Count the usage of AMR/H codec by channel mode requested."}, + [BSC_CTR_CODEC_EFR] = {"bts.codec_efr", "Count the usage of EFR codec by channel mode requested."}, + [BSC_CTR_CODEC_V1_FR] = {"bts.codec_fr", "Count the usage of FR codec by channel mode requested."}, + [BSC_CTR_CODEC_V1_HR] = {"bts.codec_hr", "Count the usage of HR codec by channel mode requested."}, }; enum { diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 4c8448e..daef312 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -82,6 +82,39 @@ lchan_free(lchan); } +static void count_codecs(struct gsm_bts *bts, struct gsm_lchan *lchan) +{ + if (lchan->type == GSM_LCHAN_TCH_H) { + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_AMR: + rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_H]); + break; + case GSM48_CMODE_SPEECH_V1: + rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_HR]); + break; + default: + break; + } + } else if (lchan->type == GSM_LCHAN_TCH_F) { + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_AMR: + rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_F]); + break; + case GSM48_CMODE_SPEECH_V1: + rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_FR]); + break; + case GSM48_CMODE_SPEECH_EFR: + rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_EFR]); + break; + default: + break; + } + } else { + LOGP(DRSL, LOGL_ERROR, "count_codecs unknown lchan->type %x on channel %s\n", + lchan->type, gsm_ts_and_pchan_name(lchan->ts)); + } +} + static uint8_t mdisc_by_msgtype(uint8_t msg_type) { /* mask off the transparent bit ? */ @@ -1164,6 +1197,7 @@ lchan->rqd_ta = 0; } + count_codecs(msg->trx->bts, lchan); send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL); return 0; @@ -1472,6 +1506,7 @@ rc = rsl_rx_rf_chan_rel_ack(msg->lchan); break; case RSL_MT_MODE_MODIFY_ACK: + count_codecs(msg->trx->bts, msg->lchan); DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name); break; case RSL_MT_MODE_MODIFY_NACK: -- To view, visit https://gerrit.osmocom.org/794 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifc8a406a11dce16b9e7f3310841e470545550a2c Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 12 14:12:41 2016 From: gerrit-no-reply at lists.osmocom.org (lynxis lazus) Date: Mon, 12 Sep 2016 14:12:41 +0000 Subject: [PATCH] openbsc[master]: msc: add counters to track call attempts/active/success/failed In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/795 to look at the new patch set (#2). msc: add counters to track call attempts/active/success/failed active_calls describe all calls in active state. call.complete Call got terminated by disconnect requested either by MS or MSC. call.incomplete Call got terminated by any other reason. call.active Calls reached active state. Change-Id: I49b93af2e6a0ba16c2fb00b7b83974e8a6a16df3 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/net_init.c M openbsc/src/libmsc/gsm_04_08.c 3 files changed, 42 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/95/795/2 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..e73c581 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -202,6 +202,9 @@ MSC_CTR_CALL_MO_CONNECT_ACK, MSC_CTR_CALL_MT_SETUP, MSC_CTR_CALL_MT_CONNECT, + MSC_CTR_CALL_ACTIVE, + MSC_CTR_CALL_COMPLETE, + MSC_CTR_CALL_INCOMPLETE, }; static const struct rate_ctr_desc msc_ctr_description[] = { @@ -221,6 +224,9 @@ [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, [MSC_CTR_CALL_MT_SETUP] = {"call.mt_setup", "Sent setup requests to the MS (MT)."}, [MSC_CTR_CALL_MT_CONNECT] = {"call.mt_connect", "Sent a connect to the MS (MT)."}, + [MSC_CTR_CALL_ACTIVE] = {"call.active", "Count amount of calls reached state active."}, + [MSC_CTR_CALL_COMPLETE] = {"call.complete", "Count amount of calls which got terminated by disconnect req or ind after reaching active state."}, + [MSC_CTR_CALL_INCOMPLETE] = {"call.incomplete", "Call got terminated by any other reason."}, }; @@ -284,7 +290,7 @@ struct rate_ctr_group *bsc_ctrs; struct rate_ctr_group *msc_ctrs; - + struct osmo_counter *active_calls; /* layer 4 */ struct mncc_sock_state *mncc_state; diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 65419ae..f145985 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -83,6 +83,7 @@ /* init statistics */ net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0); net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0); + net->active_calls = osmo_counter_alloc("msc.active_calls"); net->mncc_recv = mncc_recv; net->ext_min = GSM_MIN_EXTEN; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c30fbb0..a1d9cf3 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1306,6 +1306,39 @@ return gsm48_conn_sendmsg(msg, conn, NULL); } +/* FIXME: this count_statistics is a state machine behaviour. we should convert + * the complete call control into a state machine. Afterwards we can move this + * code into state transitions. + */ +static void count_statistics(struct gsm_trans *trans, int new_state) +{ + int old_state = trans->cc.state; + struct rate_ctr_group *msc = trans->net->msc_ctrs; + + if (old_state == new_state) + return; + + /* state incoming */ + switch (new_state) { + case GSM_CSTATE_ACTIVE: + osmo_counter_inc(trans->net->active_calls); + rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_ACTIVE]); + break; + } + + /* state outgoing */ + switch (old_state) { + case GSM_CSTATE_ACTIVE: + osmo_counter_dec(trans->net->active_calls); + if (new_state == GSM_CSTATE_DISCONNECT_REQ || + new_state == GSM_CSTATE_DISCONNECT_IND) + rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]); + else + rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]); + break; + } +} + /* Call Control */ /* The entire call control code is written in accordance with Figure 7.10c @@ -1322,6 +1355,7 @@ gsm48_cc_state_name(trans->cc.state), gsm48_cc_state_name(state)); + count_statistics(trans, state); trans->cc.state = state; } -- To view, visit https://gerrit.osmocom.org/795 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I49b93af2e6a0ba16c2fb00b7b83974e8a6a16df3 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: lynxis lazus From gerrit-no-reply at lists.osmocom.org Mon Sep 12 14:24:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 12 Sep 2016 14:24:02 +0000 Subject: osmo-pcu[master]: tbf: add llc_queue_size() to check llc_queue is valid before... In-Reply-To: References: Message-ID: Patch Set 2: New code can easily again use llc_queue()->size() by accident, where C++ would technically have the tools in place to make unwanted access private. AFAICT all callers of llc_queue() are now private, right? So we could make llc_queue() private altogether. The few private callers could then add an explicit null pointer check. (not to be confused with GprsMs::llc_queue()). -- To view, visit https://gerrit.osmocom.org/724 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88cc3180f8f86785e3f07981895dabddf50b60a2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 13 13:11:44 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 13 Sep 2016 13:11:44 +0000 Subject: [PATCH] openbsc[master]: RAB parameters: use shorter 32 bit IP address format Message-ID: Review at https://gerrit.osmocom.org/844 RAB parameters: use shorter 32 bit IP address format This is needed for the ip.access nano3G femto cell, which does not support x213 NSAP encapsulation (56bit for an IPv4 address). Other femto cells seem to also support the 32bit format well, so it currently makes sense to have this as default. At some point we will want a VTY configuration for this. Change-Id: I8282889513cd64d180905b5c603b6ee4abc8c7d2 --- M openbsc/src/gprs/gprs_gmm.c M openbsc/src/gprs/sgsn_libgtp.c 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/44/844/1 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 8de3bf7..138357f 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -793,7 +793,7 @@ /* Send RAB activation requests for all PDP contexts */ struct sgsn_pdp_ctx *pdp; llist_for_each_entry(pdp, &ctx->pdp_list, list) { - iu_rab_act_ps(pdp->nsapi, pdp, 1); + iu_rab_act_ps(pdp->nsapi, pdp, 0); } } #endif diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 04bd40a..6a8c463 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -369,7 +369,7 @@ } else if (pctx->mm->ran_type == MM_CTX_T_UTRAN_Iu) { #ifdef BUILD_IU /* Activate a radio bearer */ - iu_rab_act_ps(pdp->nsapi, pctx, 1); + iu_rab_act_ps(pdp->nsapi, pctx, 0); return 0; #else return -ENOTSUP; -- To view, visit https://gerrit.osmocom.org/844 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8282889513cd64d180905b5c603b6ee4abc8c7d2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 13 13:21:25 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 13 Sep 2016 13:21:25 +0000 Subject: [ABANDON] openbsc[master]: RAB parameters: use shorter 32 bit IP address format In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: RAB parameters: use shorter 32 bit IP address format ...................................................................... Abandoned no, other femto cells do not all support the 32bit address format. We need a VTY config instead. -- To view, visit https://gerrit.osmocom.org/844 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I8282889513cd64d180905b5c603b6ee4abc8c7d2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 13 16:39:38 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 13 Sep 2016 16:39:38 +0000 Subject: libosmo-abis[master]: osmo_ortp.c: fix order of set_connected_mode and set_remote_... In-Reply-To: References: Message-ID: Patch Set 1: This is revert of 8c119f7a0510b75e7fa1b96a37f2a6650e13824f - would be better if it were marked as such. -- To view, visit https://gerrit.osmocom.org/815 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I92308ddffc376af8d4d65e6b9cbeee222b7bff5e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 13 23:28:54 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 13 Sep 2016 23:28:54 +0000 Subject: osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (1 comment) fine except for one fatal detail. https://gerrit.osmocom.org/#/c/832/2/src/tbf.cpp File src/tbf.cpp: Line 1239: void gprs_rlcmac_dl_tbf::calc_egprs_window_size() Since the function is now in gprs_rlcmac_dl_tbf, it should obviously be in file tbf_dl.cpp like the other gprs_rlcmac_dl_tbf:: functions. -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 13 23:42:39 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 13 Sep 2016 23:42:39 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-1 (1 comment) fine except for the luring null pointer segfault https://gerrit.osmocom.org/#/c/798/4/src/tbf.cpp File src/tbf.cpp: Line 380: gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); If this happens to not be a dl_tbf instance, as_dl_tbf() will return NULL. You need to guard against that. side note: In puristic C++ thought, this is a bit ugly: adding child class functionality in the base class is Not Good (tm). But class gprs_rlcmac_tbf seems to have been designed this way... So I guess it's not your fault, and on the plus side this avoids the overhead of virtual functions. "Class inheritance is highly overrated" -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 00:36:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 00:36:32 +0000 Subject: osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (15 comments) https://gerrit.osmocom.org/#/c/819/1//COMMIT_MSG Commit Message: Line 9: Earlier number of TS allocation for second DL TBF was less compared (some extra spaces around 'DL') Line 10: Compared to first TBF. As the allocation was considering combined capacity 'compared Compared' and your sentence is weird: "Earlier allocation for second was less than first" ?? Keep it simple :) Line 11: for TS allocation which was causing inconsistencies. I don't understand the "As the allocation ... was causing inconsistencies" sentence at all. What inconsistency in detail? Line 12: This patch controls the TS allocation based on direction configured. "controls the allocation"? Again rather name it in detail what the patch changes. https://gerrit.osmocom.org/#/c/819/1/src/bts.cpp File src/bts.cpp: Line 629: if (bts->capacity_type == 1) looks like we'd typically use a switch() here, instead. https://gerrit.osmocom.org/#/c/819/1/src/bts.h File src/bts.h: Line 203: */ Do you intentionally define the values 1, 2, 3 to map to the enum values 0, 1, 2? If capacity_type == 0 is not a valid indicator for empty, I'd rather define values 0, 1, 2. If == 0 is a valid indicator, you'd also need a kind of DL_NONE enum value to return in get_ts_allocation_type(). Line 294: /* get TS allocation type */ The comment is worthless as it reflects the function name 1:1. https://gerrit.osmocom.org/#/c/819/1/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 780: if (capacity_type == UL_ONLY) { naming the value gotten from get_ts_allocation_type() again 'capacity_type' like the uint8_t in struct gprs_rlcmac_bts made me think that this is a mapping mistake between the enum and the uint8_t. What is it, a capacity_type or a ts_allocation_type? To make things worse, the enum is called allocation_capacity. Better to stick with one naming consistently. https://gerrit.osmocom.org/#/c/819/1/src/pcu_main.cpp File src/pcu_main.cpp: Line 220: bts->capacity_type = 3; I dislike that you're using the numbers 1, 2, 3 in various places to mean things instead of defining as names in an enum. If enum allocation_capacity matched the uint8_t values, you could use those names. https://gerrit.osmocom.org/#/c/819/1/src/pcu_vty.c File src/pcu_vty.c: Line 504: "enable DL capacity based allocation support\n" So to summarize, "the capacity type is a TS allocation that is configured based on capacity; I can enable support for DL or UL". I find this rather hard to understand, I think you can do better than this. It looks like you need to decide for one proper name and description and use that consistently everywhere, and try to drop meaningless buzzwords where possible. Maybe you could first describe how this works in detail in the commit log, and then we can come back to a crisp and concise summary here? Line 513: else it is impossible to enter this 'else', since the VTY will only allow exactly either 'dl' or 'ul' to be passed. Do you mean to have '(dl|ul|both)' above? https://gerrit.osmocom.org/#/c/819/1/tests/alloc/AllocTest.cpp File tests/alloc/AllocTest.cpp: Line 829: printf("TBF1: numTs1(%d)\n", numTs1); I don't see why you'd add a "1" to "numTs", it says TBF1 already. If you need to, this should already have been so in the previous patch. Line 841: OSMO_ASSERT(numTs2 == numTs1); (obsolete assertion Ts2 == Ts1) Line 865: unrelated whitespace ... you should know by now ;) Please read your own patches? https://gerrit.osmocom.org/#/c/819/1/tests/alloc/AllocTest.ok File tests/alloc/AllocTest.ok: Line 10798: TBF2: numTs2(4) see, now we have an added 1 and 2 instead of just the second TBF being fixed to be 4. -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 00:37:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 00:37:51 +0000 Subject: osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... In-Reply-To: References: Message-ID: Patch Set 1: (2 comments) pretty close to a +2 https://gerrit.osmocom.org/#/c/818/1/tests/alloc/AllocTest.cpp File tests/alloc/AllocTest.cpp: Line 821: numTs1++; missing indent Line 840: OSMO_ASSERT(numTs2 != numTs1); numTs1 == 4 and numTs2 == 3 as guaranteed by above assertions, so the numTs2 != numTs1 assertion is obsolete. -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 00:51:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 00:51:49 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Patch Set 1: (5 comments) https://gerrit.osmocom.org/#/c/825/1//COMMIT_MSG Commit Message: Line 11: in 44.060. The test's expectation is corrected along with the bug Preferably name it as ETSI TS or 3GPP explicitly with full version information. https://gerrit.osmocom.org/#/c/825/1/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 500: * TODO: simulate row 4 of Table 10.4.14a.1 The reference to Table 10.4... is worthless without the full document name. Line 522: OSMO_ASSERT(chunks[0].is_complete); you say "TODO: it should be complete" yet you assert that it is complete? I'd have expected the bug to cause is_complete == 0 then? https://gerrit.osmocom.org/#/c/825/1/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 663: MS_RA_capability_value[0].u.Content. You're using ulreq.u.Packet_Resource_Request N times, if you fetch it into a local pointer var first you could make these lines a lot shorter. Same for ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. MS_RA_capability_value[0].u below. This would improve readability dramatically. Line 2011: ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, if tbf_li_decoding() is used only by this test, IMHO it should be defined right above test_tbf_li_decoding(), not a thousand lines further above. -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:10:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:10:47 +0000 Subject: osmo-pcu[master]: EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (6 comments) https://gerrit.osmocom.org/#/c/826/1//COMMIT_MSG Commit Message: Line 7: EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 "EPGRS: fix interpretation of length indicator in RLC data block" Line 10: Which has been fixed in this patch. It would be good to briefly describe in what way the handling was not proper before this patch, so that I don't need to look up the spec to understand. Nevertheless, of course keep the reference to the table, add the full document name and version. https://gerrit.osmocom.org/#/c/826/1/src/decoding.cpp File src/decoding.cpp: Line 77: chunks[num_chunks].is_complete = true; Are you sure is_complete shall always be true here? The spec says "The current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or continues in the next RLC data blcok[sic]" So IIUC the PDU might continue in the next data block and thus might not be complete yet? If this is correct, you should/could join this 'else if' with above 'if', they are identical and li->e would be don't-care. https://gerrit.osmocom.org/#/c/826/1/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 501: rdbi.cv = 1; why this change from 0 to 1? I'd have expected the test to remain unchanged except for the final assertions. Line 513: OSMO_ASSERT(chunks[1].offset == 1); could these additional asserts already be in the previous patch (with differing values)? https://gerrit.osmocom.org/#/c/826/1/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 731: /* row 4 of Table 10.4.14a.1 */ this should be in the previous patch with a proper reference to the full document name. -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:12:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:12:33 +0000 Subject: openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Patch Set 1: The build failure is from the added $(NULL) in 'TESTSUITE = ' added in the preceding patch. -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:15:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:15:17 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 7: Code-Review-1 you haven't fixed the three missing indents commented on in patch set 6. -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:25:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:25:23 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 22: Code-Review-1 (2 comments) https://gerrit.osmocom.org/#/c/416/22/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 48: ~egprs_compress(); Are you implementing this destructor anywhere? Did you make it private on purpose? https://gerrit.osmocom.org/#/c/416/22/tests/testsuite.at File tests/testsuite.at: Line 26: drop extra blank line -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 22 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:26:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:26:23 +0000 Subject: osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:26:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:26:27 +0000 Subject: osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:26:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:26:34 +0000 Subject: [MERGED] osmo-pcu[master]: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds ...................................................................... Fix CSN1 decoding: CSN_LEFT_ALIGNED_VAR_BMP bounds Fix attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation was flawed, and in the final step, 8 bits were read instead of the remainder < 8. This lead to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Instead, read 8 bits only as long as at least 8 bits remain, and read any remaining bits < 8 in a final step. Drop unneeded nB1 variable and an obvious comment. Adjust the unit test assertion in testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp. Based on a fix by Aravind Sirsikar , but implemented differently. Related: OS#1805 Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 --- M src/csn1.cpp M tests/rlcmac/RLCMACTest.cpp 2 files changed, 6 insertions(+), 12 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved arvind.sirsikar: Looks good to me, but someone else must approve Harald Welte: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/src/csn1.cpp b/src/csn1.cpp index d51fe83..a1698a5 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -1110,22 +1110,21 @@ { /* extract bits */ guint8* pui8 = pui8DATA(data, pDescr->offset); - gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */ - while (no_of_bits > 0) + while (no_of_bits >= 8) { *pui8 = bitvec_read_field(vector, readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } - if (nB1 > 0) + if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; - no_of_bits -= nB1; - bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */ + bit_offset += no_of_bits; + no_of_bits = 0; } } } diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index f633dd8..97e5e60 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -223,13 +223,8 @@ &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; decode_gsm_rlcmac_uplink(vector, &data); - /* - * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 - * bits should be decoded. The 13th byte should end up as 0x00, but we - * see data coming from bitvec_get_bit_pos() returning -EINVAL. - */ OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), - "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); + "7f ff ff ee 00 00 00 00 00 00 00 00 00 ")); } int main(int argc, char *argv[]) -- To view, visit https://gerrit.osmocom.org/805 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I490498c8da6b531f54acb673379379f7b10907c0 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:26:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:26:34 +0000 Subject: [MERGED] osmo-pcu[master]: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP ...................................................................... CSN1 decoding: add test to show bug in CSN_LEFT_ALIGNED_VAR_BMP CSN1 decoding currently contains an attempted read past vector boundaries in case of a starting bit offset != 0, so that the last amount of bits read should be < 8. In the case of CSN_LEFT_ALIGNED_VAR_BMP, the mod-8 calculation is flawed, and in what should be the final step of reading n < 8 bits, 8 bits are read instead of n (with an extraneous read of n bits following after that). This leads to -EINVAL being returned by bitvec_get_bit_pos() and bogus resulting data. Add testCsnLeftAlignedVarBmpBounds() in RLCMACTest.cpp to show and expect this bug. The test's expectation shall be corrected along with the bug fix in a subsequent commit. Related: OS#1805 Tweaked-by: Neels Hofmeyr Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 --- M tests/rlcmac/RLCMACTest.cpp 1 file changed, 22 insertions(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved arvind.sirsikar: Looks good to me, but someone else must approve Harald Welte: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index 466b89e..f633dd8 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -30,6 +30,7 @@ #include "pcu_vty.h" #include #include +#include #include } using namespace std; @@ -211,6 +212,26 @@ bitvec_free(resultVector); } +void testCsnLeftAlignedVarBmpBounds() +{ + bitvec *vector = bitvec_alloc(23); + + bitvec_unhex(vector, "40200bffd161003e0e519ffffffb800000000000000000"); + RlcMacUplink_t data; + + EGPRS_AckNack_Desc_t *urbb = + &data.u.Egprs_Packet_Downlink_Ack_Nack.EGPRS_AckNack.Desc; + decode_gsm_rlcmac_uplink(vector, &data); + + /* + * TODO: URBB len is decoded as 102 bits. So 96 + 6 bits = 12 bytes + 6 + * bits should be decoded. The 13th byte should end up as 0x00, but we + * see data coming from bitvec_get_bit_pos() returning -EINVAL. + */ + OSMO_ASSERT(!strcmp(osmo_hexdump(urbb->URBB, 13), + "7f ff ff ee 00 00 00 00 00 00 00 00 ea ")); +} + int main(int argc, char *argv[]) { osmo_init_logging(&gprs_log_info); @@ -218,5 +239,5 @@ //printSizeofRLCMAC(); testRlcMacDownlink(); testRlcMacUplink(); - + testCsnLeftAlignedVarBmpBounds(); } -- To view, visit https://gerrit.osmocom.org/804 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4641f5d1d49f66cb1a5cd813befb3a2a266001b0 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 01:32:46 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 01:32:46 +0000 Subject: openbsc[master]: lchan: Release channel in case of late activation ack In-Reply-To: References: Message-ID: Patch Set 3: Note to self: I should test this with dyn TS. -- To view, visit https://gerrit.osmocom.org/713 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I63dc0deaf15ba7c21e20b1e0c7b85f0437e183ed Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 05:10:52 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Wed, 14 Sep 2016 05:10:52 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 7: I have checked the patch with checkpatch.pl and it has not shown any indentation error. -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:29:11 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Wed, 14 Sep 2016 06:29:11 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 22: (1 comment) https://gerrit.osmocom.org/#/c/416/22/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 48: ~egprs_compress(); > Are you implementing this destructor anywhere? Read through Holger's comments on the patch set 15. It was implemented as per his recommendation. Thanks. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 22 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:32:09 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Wed, 14 Sep 2016 06:32:09 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Hello Max, Neels Hofmeyr, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/416 to look at the new patch set (#23). EGPRS: Add EPDAN CRBB Tree based decoding Implemented tree based algorithm to decode compressed bitmap in EPDAN as described in section 9.1.10 of 3GPP 44.060. This algorithm intends to improve the performance over existing method. New Regression test is added under bitcomp directory. Test case is added to validate decompressed result of the bitmap Present in EPDAN. Test is done for multiple bitmaps of varying length. Invalid inputs are also part of the test vector. Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce --- M src/Makefile.am M src/decoding.cpp A src/egprs_rlc_compression.cpp A src/egprs_rlc_compression.h M tests/Makefile.am A tests/bitcomp/BitcompTest.cpp A tests/bitcomp/BitcompTest.err A tests/bitcomp/BitcompTest.ok M tests/testsuite.at 9 files changed, 784 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/16/416/23 diff --git a/src/Makefile.am b/src/Makefile.am index 9bdec2f..9b047e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,7 +62,8 @@ rlc.cpp \ osmobts_sock.cpp \ gprs_codel.c \ - gprs_coding_scheme.cpp + gprs_coding_scheme.cpp \ + egprs_rlc_compression.cpp bin_PROGRAMS = \ osmo-pcu @@ -94,7 +95,8 @@ pcu_utils.h \ cxx_linuxlist.h \ gprs_codel.h \ - gprs_coding_scheme.h + gprs_coding_scheme.h \ + egprs_rlc_compression.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..60ebc0d 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -20,6 +20,7 @@ #include #include #include +#include extern "C" { #include @@ -695,21 +696,17 @@ if (crbb_len > 0) { int old_len = bits->cur_bit; - struct bitvec crbb; - crbb.data = (uint8_t *)desc->CRBB; - crbb.data_len = sizeof(desc->CRBB); - crbb.cur_bit = desc->CRBB_LENGTH; - - rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE, - bits); - + LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exist, " + "CRBB LEN =%d and Starting color code =%d", + desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE); + rc = decompress_crbb(desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE, + desc->CRBB, bits); if (rc < 0) { LOGP(DRLCMACUL, LOGL_NOTICE, - "Failed to decode CRBB: " - "length %d, data '%s'\n", - desc->CRBB_LENGTH, - osmo_hexdump(crbb.data, crbb.data_len)); + "Failed to decode CRBB: length %d, data '%s'\n", + desc->CRBB_LENGTH, osmo_hexdump( + desc->CRBB, (desc->CRBB_LENGTH + 7)/8)); /* We don't know the SSN offset for the URBB, * return what we have so far and assume the * bitmap has stopped here */ diff --git a/src/egprs_rlc_compression.cpp b/src/egprs_rlc_compression.cpp new file mode 100644 index 0000000..4a1f598 --- /dev/null +++ b/src/egprs_rlc_compression.cpp @@ -0,0 +1,337 @@ +/* egprs_rlc_compression.h +* Routines for EGPRS RLC bitmap compression handling +*/ +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +extern void *tall_pcu_ctx; +extern const char *one_run_len_code_list[MAX_CDWDTBL_LEN]; +extern const char *zero_run_len_code_list[MAX_CDWDTBL_LEN]; + +egprs_compress *egprs_compress::s_instance = 0; + +/* Function to create tree node */ +Node *egprs_compress::create_tree_node(void *parent) +{ + Node *new_node; + + new_node = talloc_zero(parent, Node); + new_node->left = NULL; + new_node->right = NULL; + new_node->run_length = -1; + return new_node; +} + +/* Function to build the codeword tree + * \param root[in] Root of Ones or Zeros tree + * \param cdwd[in] Code word + */ +void egprs_compress::build_codeword(Node *root, const char *cdwd[]) +{ + Node *iter; + int len; + int i; + int idx; + + for (idx = 0; idx < MAX_CDWDTBL_LEN; idx++) { + len = strlen((const char *)cdwd[idx]); + iter = root; + for (i = 0; i < len; i++) { + if (cdwd[idx][i] == '0') { + if (!iter->left) + iter->left = create_tree_node(root); + iter = iter->left; + } else if (cdwd[idx][i] == '1') { + if (!iter->right) + iter->right = create_tree_node(root); + iter = iter->right; + } + } + if (iter) { + if (idx < 64) + (iter->run_length) = idx; + else + (iter->run_length) = (idx - 63) * 64; + } + } +} + +const char *one_run_len_code_list[MAX_CDWDTBL_LEN] = { + "00110101", + "000111", + "0111", + "1000", + "1011", + "1100", + "1110", + "1111", + "10011", + "10100", + "00111", + "01000", + "001000", + "000011", + "110100", + "110101", + "101010", + "101011", + "0100111", + "0001100", + "0001000", + "0010111", + "0000011", + "0000100", + "0101000", + "0101011", + "0010011", + "0100100", + "0011000", + "00000010", + "00000011", + "00011010", + "00011011", + "00010010", + "00010011", + "00010100", + "00010101", + "00010110", + "00010111", + "00101000", + "00101001", + "00101010", + "00101011", + "00101100", + "00101101", + "00000100", + "00000101", + "00001010", + "00001011", + "01010010", + "01010011", + "01010100", + "01010101", + "00100100", + "00100101", + "01011000", + "01011001", + "01011010", + "01011011", + "01001010", + "01001011", + "00110010", + "00110011", + "00110100", + "11011", + "10010", + "010111", + "0110111", + "00110110", + "00110111", + "01100100", + "01100101", + "01101000", + "01100111", + "011001100", + "011001101", + "011010010", + "011010011", + "011010100" +}; + +const char *zero_run_len_code_list[MAX_CDWDTBL_LEN] = { + "0000110111", + "10", + "11", + "010", + "011", + "0011", + "0010", + "00011", + "000101", + "000100", + "0000100", + "0000101", + "0000111", + "00000100", + "00000111", + "000011000", + "0000010111", + "0000011000", + "0000001000", + "00001100111", + "00001101000", + "00001101100", + "00000110111", + "00000101000", + "00000010111", + "00000011000", + "000011001010", + "000011001011", + "000011001100", + "000011001101", + "000001101000", + "000001101001", + "000001101010", + "000001101011", + "000011010010", + "000011010011", + "000011010100", + "000011010101", + "000011010110", + "000011010111", + "000001101100", + "000001101101", + "000011011010", + "000011011011", + "000001010100", + "000001010101", + "000001010110", + "000001010111", + "000001100100", + "000001100101", + "000001010010", + "000001010011", + "000000100100", + "000000110111", + "000000111000", + "000000100111", + "000000101000", + "000001011000", + "000001011001", + "000000101011", + "000000101100", + "000001011010", + "000001100110", + "000001100111", + "0000001111", + "000011001000", + "000011001001", + "000001011011", + "000000110011", + "000000110100", + "000000110101", + "0000001101100", + "0000001101101", + "0000001001010", + "0000001001011", + "0000001001100", + "0000001001101", + "0000001110010", + "0000001110011" +}; + +/* search_runlen function will return the runlength for the codeword + * \param root[in] Root of Ones or Zeros tree + * \param bmbuf[in] Recevied compressed bitmap buf + * \param bit_pos[in] The start bit pos to read codeword + * \param len_codewd[in] Length of code word + * \param rlen[out] Run length value + */ +static int search_runlen( + Node *root, + const uint8_t *bmbuf, + uint8_t bit_pos, + uint8_t *len_codewd, + uint16_t *rlen) +{ + Node *iter; + uint8_t dir; + + iter = root; + *len_codewd = 0; + + while (iter->run_length == -1) { + if ((!iter->left) && (!iter->right)) + return -1; + /* get the bit value at the bitpos and put it in right most of dir */ + dir = ((bmbuf[BITS_TO_BYTES(bit_pos)-1] + >>(7-(MOD8(bit_pos)))) & 0x01); + (bit_pos)++; + (*len_codewd)++; + if (((dir&0x01) == 0) && (iter->left != NULL)) + iter = iter->left; + else if (((dir&0x01) == 1) && (iter->right != NULL)) + iter = iter->right; + else + return -1; + } + LOGP(DRLCMACUL, LOGL_DEBUG, "Run_length = %d\n", iter->run_length); + (*rlen) = (iter->run_length); + return 1; +} + +/* Function to decompress crbb + * \param compress_bmap_len[in] Compressed bitmap length + * \param clr_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength + * \param orig_crbb_buf[in] Received block crbb bitmap + * \param dest[out] Uncompressed bitvector + */ +int decompress_crbb( + int8_t compress_bmap_len, + uint8_t clr_code_bit, + const uint8_t *orig_crbb_buf, + bitvec *dest) +{ + + uint8_t bit_pos = 0; + uint8_t data = 0x0; + node *list = NULL; + uint8_t nbits = 0; /* number of bits of codeword */ + uint16_t run_length = 0; + uint16_t cbmaplen = 0; /* compressed bitmap part after decompression */ + unsigned wp = dest->cur_bit; + int rc = 0; + egprs_compress *compress = egprs_compress::instance(); + + while (compress_bmap_len > 0) { + if (clr_code_bit == 1) { + data = 0xff; + list = compress->ones_list; + } else { + data = 0x00; + list = compress->zeros_list; + } + rc = search_runlen(list, orig_crbb_buf, + bit_pos, &nbits, &run_length); + if (rc == -1) + return -1; + /* If run length > 64, need makeup and terminating code */ + if (run_length < 64) + clr_code_bit ? clr_code_bit = 0 : clr_code_bit = 1; + cbmaplen = cbmaplen + run_length; + /* put run length of Ones in uncompressed bitmap */ + while (run_length != 0) { + if (run_length > 8) { + bitvec_write_field(dest, wp, data, 8); + run_length = run_length - 8; + } else { + bitvec_write_field(dest, wp, data, run_length); + run_length = 0; + } + } + bit_pos = bit_pos + nbits; + compress_bmap_len = compress_bmap_len - nbits; + } + return 0; +} + +/* init function to build codeword */ +int egprs_compress::decode_tree_init() +{ + ones_list = create_tree_node(tall_pcu_ctx); + zeros_list = create_tree_node(tall_pcu_ctx); + build_codeword(ones_list, one_run_len_code_list); + build_codeword(zeros_list, zero_run_len_code_list); + return 0; +} diff --git a/src/egprs_rlc_compression.h b/src/egprs_rlc_compression.h new file mode 100644 index 0000000..2ec00da --- /dev/null +++ b/src/egprs_rlc_compression.h @@ -0,0 +1,49 @@ +/* egprs_rlc_compression.h + * Routines for EGPRS RLC bitmap compression handling + */ + +#pragma once + +#define MAX_CDWDTBL_LEN 79 /* total number of codewords */ +#define BITS_TO_BYTES(X) ((X ? (X/8):0)+1) +#define MOD8(X) (((X)+8) & (0x07)) + +typedef struct node { + struct node *left; + struct node *right; + int run_length; +} Node; + +int decompress_crbb(int8_t compress_bmap_len, uint8_t clr_code_bit, + const uint8_t *orig_buf, bitvec *dest); + +/* Creating singleton class*/ +class egprs_compress +{ +public: + Node *ones_list; + Node *zeros_list; + + int decode_tree_init(void); + + static egprs_compress *instance() + { + if (!s_instance) + s_instance = new egprs_compress; + + return s_instance; + } +private: + static egprs_compress *s_instance; + + egprs_compress() + { + if (decode_tree_init() < 0) { + fprintf(stderr, "Error initializing tree\n"); + exit(1); + } + } + Node *create_tree_node(void *); + void build_codeword(Node *root, const char *cdwd[]); + ~egprs_compress(); +}; diff --git a/tests/Makefile.am b/tests/Makefile.am index 2a3415e..a24f4ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/ AM_LDFLAGS = -lrt -check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest +check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest noinst_PROGRAMS = emu/pcu_emu rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp @@ -23,6 +23,11 @@ $(top_builddir)/src/libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(COMMON_LA) + +bitcomp_BitcompTest_SOURCES = bitcomp/BitcompTest.cpp ../src/egprs_rlc_compression.cpp +bitcomp_BitcompTest_LDADD = \ $(LIBOSMOCORE_LIBS) \ $(COMMON_LA) @@ -108,6 +113,7 @@ rlcmac/RLCMACTest.ok rlcmac/RLCMACTest.err \ alloc/AllocTest.ok alloc/AllocTest.err \ tbf/TbfTest.ok tbf/TbfTest.err \ + bitcomp/BitcompTest.ok bitcomp/BitcompTest.err \ types/TypesTest.ok types/TypesTest.err \ ms/MsTest.ok ms/MsTest.err \ llc/LlcTest.ok llc/LlcTest.err \ diff --git a/tests/bitcomp/BitcompTest.cpp b/tests/bitcomp/BitcompTest.cpp new file mode 100644 index 0000000..3092872 --- /dev/null +++ b/tests/bitcomp/BitcompTest.cpp @@ -0,0 +1,237 @@ +#include +#include + +#include "rlc.h" +#include "gprs_debug.h" +#include +#include "egprs_rlc_compression.h" + +extern "C" { +#include +#include +#include +#include +} + +#define NEW 1 +#define MASK(n) (0xFF << (8-n)) +#define MAX_CRBB_LEN 23 +#define MAX_URBB_LEN 40 + +void *tall_pcu_ctx; + +struct test_data { + int8_t crbb_len; + uint8_t cc; + uint8_t crbb_data[MAX_CRBB_LEN]; /* compressed data */ + uint8_t ucmp_data[MAX_URBB_LEN]; /* uncompressed data */ + int ucmp_len; + int verify; +} test[] = { + { .crbb_len = 67, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xdb + }, + .ucmp_len = 194, .verify = 1 + }, + { .crbb_len = 40, .cc = 1, + .crbb_data = { + 0x53, 0x06, 0xc5, 0x40, 0x6d + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x03 + }, + .ucmp_len = 182, .verify = 1 + }, + { .crbb_len = 8, .cc = 1, + .crbb_data = {0x02}, + .ucmp_data = {0xff, 0xff, 0xff, 0xf8}, + .ucmp_len = 29, .verify = 1 + }, + { .crbb_len = 103, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03, + 0x71, 0xb0, 0x6e, 0x24 + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff + }, + .ucmp_len = 288, .verify = 1 + }, + /* Test vector from libosmocore test */ + { .crbb_len = 35, .cc = 0, + .crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80}, + .ucmp_data = {0x37, 0x47, 0x81, 0xf0}, + .ucmp_len = 28, .verify = 1 + }, + { .crbb_len = 18, .cc = 1, + .crbb_data = {0xdd, 0x41, 0x00}, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00 + }, + .ucmp_len = 90, .verify = 1 + }, + /*Invalid inputs*/ + { .crbb_len = 18, .cc = 1, + .crbb_data = {0x1E, 0x70, 0xc0}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 14, .cc = 1, + .crbb_data = {0x00, 0x1E, 0x7c}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 24, .cc = 0, + .crbb_data = {0x00, 0x00, 0x00}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + } + }; + +static const struct log_info_cat default_categories[] = { + {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, + {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, + {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1}, + {"DNS", "\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO, 1}, + {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO, 1}, + {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1}, +}; + +static int filter_fn(const struct log_context *ctx, + struct log_target *tar) +{ + return 1; +} + +/* To verify the result with expected result */ +int check_result(bitvec bits, uint8_t *exp_data, int exp_len) +{ + if (bits.cur_bit != exp_len) + return 0; + size_t n = (exp_len / 8); + int rem = (exp_len % 8); + + if (memcmp(exp_data, bits.data, n) == 0) { + if (rem == 0) + return 1; + if ((bits.data[n] & MASK(rem)) == ((*(exp_data + n)) & MASK(rem))) + return 1; + else + return 0; + } else + return 0; +} + +/* To test decoding of compressed bitmap by Tree based method + * and to verify the result with expected result + * for invalid input verfication is suppressed + */ +static void test_EPDAN_decode_tree(void) +{ + bitvec dest; + int init_flag = 1; + int itr; + int rc; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + + printf("=== start %s ===\n", __func__); + + for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) { + dest.data = bits_data; + dest.data_len = sizeof(bits_data); + dest.cur_bit = 0; + memset(dest.data, 0, sizeof(bits_data)); + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTest:%d\nTree based decoding:" + "\nuncompressed data = %s\nlen = %d\n", itr + 1, + osmo_hexdump(test[itr].crbb_data, + (test[itr].crbb_len + 7)/8), test[itr].crbb_len + ); + rc = decompress_crbb(test[itr].crbb_len, test[itr].cc, + test[itr].crbb_data, &dest + ); + if (rc < 0) { + LOGP(DRLCMACUL, LOGL_NOTICE, + "\nFailed to decode CRBB: length %d, data %s", + test[itr].crbb_len, osmo_hexdump( + test[itr].crbb_data, (test[itr].crbb_len + 7)/8)); + } + if (init_flag) + init_flag = 0; + if (test[itr].verify) { + if (check_result(dest, test[itr].ucmp_data, + test[itr].ucmp_len) == 0) { + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTree based decoding" + ":Error\nexpected data = %s\nexpected" + " len = %d\ndecoded data = %s\n" + "decoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + OSMO_ASSERT(0); + } + } + LOGP(DRLCMACDL, LOGL_DEBUG, "\nexpected data = %s\nexpected len = %d" + "\ndecoded data = %s\ndecoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + } + + printf("=== end %s ===\n", __func__); +} + +const struct log_info debug_log_info = { + filter_fn, + (struct log_info_cat *)default_categories, + ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + osmo_init_logging(&debug_log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + + tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context"); + if (!tall_pcu_ctx) + abort(); + + test_EPDAN_decode_tree(); + + if (getenv("TALLOC_REPORT_FULL")) + talloc_report_full(tall_pcu_ctx, stderr); + talloc_free(tall_pcu_ctx); + return EXIT_SUCCESS; +} + +/* + * stubs that should not be reached + */ +extern "C" { +void l1if_pdch_req() { abort(); } +void l1if_connect_pdch() { abort(); } +void l1if_close_pdch() { abort(); } +void l1if_open_pdch() { abort(); } +} + diff --git a/tests/bitcomp/BitcompTest.err b/tests/bitcomp/BitcompTest.err new file mode 100644 index 0000000..7481d72 --- /dev/null +++ b/tests/bitcomp/BitcompTest.err @@ -0,0 +1,132 @@ + +Test:1 +Tree based decoding: +uncompressed data = 02 0c a0 30 cb 1a 0c e3 6c +len = 67 +Run_length = 29 +Run_length = 26 +Run_length = 30 +Run_length = 27 +Run_length = 31 +Run_length = 19 +Run_length = 32 + +expected data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +expected len = 194 +decoded data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +decoded len = 194 + +Test:2 +Tree based decoding: +uncompressed data = 53 06 c5 40 6d +len = 40 +Run_length = 50 +Run_length = 40 +Run_length = 51 +Run_length = 41 + +expected data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +expected len = 182 +decoded data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +decoded len = 182 + +Test:3 +Tree based decoding: +uncompressed data = 02 +len = 8 +Run_length = 29 + +expected data = ff ff ff f8 +expected len = 29 +decoded data = ff ff ff f8 +decoded len = 29 + +Test:4 +Tree based decoding: +uncompressed data = 02 0c e0 41 a0 0c 36 0d 03 71 b0 6e 24 +len = 103 +Run_length = 29 +Run_length = 19 +Run_length = 29 +Run_length = 20 +Run_length = 30 +Run_length = 21 +Run_length = 31 +Run_length = 22 +Run_length = 32 +Run_length = 22 +Run_length = 33 + +expected data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +expected len = 288 +decoded data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +decoded len = 288 + +Test:5 +Tree based decoding: +uncompressed data = de 88 75 65 80 +len = 35 +Run_length = 2 +Run_length = 2 +Run_length = 1 +Run_length = 3 +Run_length = 1 +Run_length = 1 +Run_length = 3 +Run_length = 4 +Run_length = 6 +Run_length = 5 + +expected data = 37 47 81 f0 +expected len = 28 +decoded data = 37 47 81 f0 +decoded len = 28 + +Test:6 +Tree based decoding: +uncompressed data = dd 41 00 +len = 18 +Run_length = 64 +Run_length = 16 +Run_length = 10 + +expected data = ff ff ff ff ff ff ff ff ff ff 00 00 +expected len = 90 +decoded data = ff ff ff ff ff ff ff ff ff ff 00 00 +decoded len = 90 + +Test:7 +Tree based decoding: +uncompressed data = 1e 70 c0 +len = 18 +Run_length = 1 +Run_length = 1 +Run_length = 2 +Run_length = 15 + +expected data = +expected len = 0 +decoded data = +decoded len = 19 + +Test:8 +Tree based decoding: +uncompressed data = 00 1e +len = 14 + +Failed to decode CRBB: length 14, data 00 1e +expected data = +expected len = 0 +decoded data = +decoded len = 0 + +Test:9 +Tree based decoding: +uncompressed data = 00 00 00 +len = 24 + +Failed to decode CRBB: length 24, data 00 00 00 +expected data = +expected len = 0 +decoded data = +decoded len = 0 diff --git a/tests/bitcomp/BitcompTest.ok b/tests/bitcomp/BitcompTest.ok new file mode 100644 index 0000000..f7720fc --- /dev/null +++ b/tests/bitcomp/BitcompTest.ok @@ -0,0 +1,2 @@ +=== start test_EPDAN_decode_tree === +=== end test_EPDAN_decode_tree === diff --git a/tests/testsuite.at b/tests/testsuite.at index 1049b31..e42a0fd 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -23,6 +23,13 @@ AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/tbf/TbfTest], [0], [expout], [experr]) AT_CLEANUP +AT_SETUP([bitcomp]) +AT_KEYWORDS([bitcomp]) +cat $abs_srcdir/bitcomp/BitcompTest.ok > expout +cat $abs_srcdir/bitcomp/BitcompTest.err > experr +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/bitcomp/BitcompTest], [0], [expout], [experr]) +AT_CLEANUP + AT_SETUP([edge]) AT_KEYWORDS([edge]) cat $abs_srcdir/edge/EdgeTest.ok > expout -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 23 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:53:39 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 06:53:39 +0000 Subject: [PATCH] osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/832 to look at the new patch set (#3). Refactoring: New function to calculate EGPRS DL window size Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h M src/tbf_dl.cpp 3 files changed, 29 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/3 diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..85d66bf 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->calc_egprs_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3c92768 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,9 @@ int release(); int abort(); + /* EGPRS: window size calculation function */ + void calc_egprs_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 489020b..c0f37e1 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -1322,3 +1322,27 @@ /* Non SPB cases 0 is reurned */ return EGPRS_RLCMAC_DL_NO_RETX; } + +/* + * This function calculates the DL window size + * for EGPRS. + */ +void gprs_rlcmac_dl_tbf::calc_egprs_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:53:39 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 06:53:39 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#5). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 11 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/5 diff --git a/src/tbf.cpp b/src/tbf.cpp index 85d66bf..fff86a0 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,13 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + + if (dl_tbf) + dl_tbf->calc_egprs_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..ea6dcdd 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..d5e8cfa 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Wed, 14 Sep 2016 06:55:56 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 7: I double checked review comment. I see an issue here. I will align it to existing and resubmit. -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 06:59:44 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 06:59:44 +0000 Subject: osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Patch Set 3: Hi Neels, I have modified the patch series as per your recommendation. Please have a look. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 07:04:41 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 14 Sep 2016 07:04:41 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 22: (1 comment) https://gerrit.osmocom.org/#/c/416/22/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 48: ~egprs_compress(); > Read through Holger's comments on the patch set 15. Private: So nobody can delete it Not implemented: So we get a link error if someone tries it. For leak checking we might just use a specialized form of destruction. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 22 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 08:53:08 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 08:53:08 +0000 Subject: [PATCH] osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/818 to look at the new patch set (#2). DL TS allocation: add test case to show TS allocation for 2nd DL TBF This patch adds a test case test_2_consecutive_dl_tbfs which expects a current bug with TS allocation for 2nd DL TBF. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1792 Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 --- M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 2 files changed, 54 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/18/818/2 diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index b636b6e..f8202a4 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -792,6 +792,56 @@ test_many_connections(alloc_algorithm_dynamic, 160, "algorithm dynamic"); } +static void test_2_consecutive_dl_tbfs() +{ + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + gprs_rlcmac_tbf *dl_tbf1, *dl_tbf2; + uint8_t numTs1 = 0, numTs2 = 0; + + printf("Testing DL TS allocation for Multi UEs\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[4].enable(); + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf1); + + for (int i = 0; i < 8; i++) { + if (dl_tbf1->pdch[i]) + numTs1++; + } + OSMO_ASSERT(numTs1 == 4); + printf("TBF1: numTs(%d)\n", numTs1); + + dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf2); + + for (int i = 0; i < 8; i++) { + if (dl_tbf2->pdch[i]) + numTs2++; + } + + /* + * TODO: currently 2nd DL TBF gets 3 TS + * This behaviour will be fixed in subsequent patch + */ + printf("TBF2: numTs(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 3); + + tbf_free(dl_tbf1); + tbf_free(dl_tbf2); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -809,6 +859,7 @@ test_alloc_b(); test_successive_allocation(); test_many_connections(); + test_2_consecutive_dl_tbfs(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 9f88186..cbb65aa 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10793,3 +10793,6 @@ TBF[31] class 14 reserves ......C. TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs +Testing DL TS allocation for Multi UEs +TBF1: numTs(4) +TBF2: numTs(3) -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 08:54:14 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 08:54:14 +0000 Subject: [PATCH] osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/818 to look at the new patch set (#3). DL TS allocation: add test case to show TS allocation for 2nd DL TBF This patch adds a test case test_2_consecutive_dl_tbfs which expects a current bug with TS allocation for 2nd DL TBF. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1792 Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 --- M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 2 files changed, 54 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/18/818/3 diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index b636b6e..f7794f7 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -792,6 +792,56 @@ test_many_connections(alloc_algorithm_dynamic, 160, "algorithm dynamic"); } +static void test_2_consecutive_dl_tbfs() +{ + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + gprs_rlcmac_tbf *dl_tbf1, *dl_tbf2; + uint8_t numTs1 = 0, numTs2 = 0; + + printf("Testing DL TS allocation for Multi UEs\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[4].enable(); + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf1); + + for (int i = 0; i < 8; i++) { + if (dl_tbf1->pdch[i]) + numTs1++; + } + OSMO_ASSERT(numTs1 == 4); + printf("TBF1: numTs(%d)\n", numTs1); + + dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf2); + + for (int i = 0; i < 8; i++) { + if (dl_tbf2->pdch[i]) + numTs2++; + } + + /* + * TODO: currently 2nd DL TBF gets 3 TS + * This behaviour will be fixed in subsequent patch + */ + printf("TBF2: numTs(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 3); + + tbf_free(dl_tbf1); + tbf_free(dl_tbf2); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -809,6 +859,7 @@ test_alloc_b(); test_successive_allocation(); test_many_connections(); + test_2_consecutive_dl_tbfs(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 9f88186..cbb65aa 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10793,3 +10793,6 @@ TBF[31] class 14 reserves ......C. TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs +Testing DL TS allocation for Multi UEs +TBF1: numTs(4) +TBF2: numTs(3) -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 09:16:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 09:16:40 +0000 Subject: osmo-pcu[master]: DL TS allocation: add test case to show TS allocation for 2n... In-Reply-To: References: Message-ID: Patch Set 3: I have modified the patch. Please have a look. -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 09:20:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 09:20:40 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#2). EGPRS: add test case to show LI decoding This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 288 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/2 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..06153b9 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate row 4 of Table 10.4.14a.1 + * should expect 1 complete. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* TODO: we should see 2 chunks here */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + /* + * TODO: it should be complete + * and length as 0 + */ + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..b00c49e 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -619,6 +619,124 @@ &ulreq, tbf->poll_fn); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts, uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) @@ -1868,6 +1986,41 @@ printf("=== end %s ===\n", __func__); } +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 09:20:46 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Wed, 14 Sep 2016 09:20:46 +0000 Subject: [PATCH] osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/430 to look at the new patch set (#8). Handle EGPRS 11 bit RACH in osmo-pcu A function is_single_block is added to get request type of RACH. EGPRS 11 bit RACH is handled. Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 --- M src/bts.cpp M src/bts.h 2 files changed, 84 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/30/430/8 diff --git a/src/bts.cpp b/src/bts.cpp index 795baa6..e917131 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -480,20 +480,16 @@ uint8_t usf = 7; uint8_t tsc; uint16_t ta; + uint16_t ms_class = 0; + uint16_t priority = 0; rach_frame(); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + if (qta < 0) qta = 0; if (qta > 252) @@ -516,8 +512,16 @@ } else { // Create new TBF #warning "Copy and paste with other routines.." - /* set class to 0, since we don't know the multislot class yet */ - tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + + if (is_11bit) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0,as we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); /* FIXME: send reject */ @@ -565,6 +569,73 @@ return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (!val) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase " + "access but we force two phase " + "access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index 801342d..ba6fc4d 100644 --- a/src/bts.h +++ b/src/bts.h @@ -290,6 +290,8 @@ int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst_type); -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 09:22:00 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 09:22:00 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/825/2/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 515: OSMO_ASSERT(num_chunks == 1); update the document here -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 09:30:22 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 09:30:22 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#3). EGPRS: add test case to show LI decoding This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 288 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/3 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..b7988a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * Need to add assert for index 1 + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..b00c49e 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -619,6 +619,124 @@ &ulreq, tbf->poll_fn); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts, uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) @@ -1868,6 +1986,41 @@ printf("=== end %s ===\n", __func__); } +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 10:45:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 10:45:34 +0000 Subject: osmo-pcu[master]: Refactoring: New function to calculate EGPRS DL window size In-Reply-To: References: Message-ID: Patch Set 3: > I have modified the patch series as per your recommendation. Please > have a look. (It's really not necessary to keep re-posting the obvious every time. I can see every new patch set in my email.) -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 10:48:55 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 14 Sep 2016 10:48:55 +0000 Subject: libosmocore[master]: gprs: Increase NS_ALLOC_SIZE to 3k In-Reply-To: References: Message-ID: Patch Set 1: This will be of limited help: ret = recvfrom(bfd->fd, msg->data, NS_ALLOC_SIZE - NS_ALLOC_HEADROOM, 0, (struct sockaddr *)saddr, &saddr_len); so you increase the buffer and an "attacker" can increase his UDP message (ip fragmentation, etc). -- To view, visit https://gerrit.osmocom.org/806 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: daniel Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 10:51:26 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 10:51:26 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#4). EGPRS: add test case to show LI decoding This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 288 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/4 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..b7988a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * Need to add assert for index 1 + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..d41d3c2 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1868,6 +1868,159 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 10:53:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 10:53:18 +0000 Subject: [PATCH] osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/832 to look at the new patch set (#4). tbf_dl: factor out EGPRS DL window size calculation A subsequent patch needs to call this from gprs_rlcmac_tbf::update(), so to avoid code dup, put the calculation in a separate function. Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h M src/tbf_dl.cpp 3 files changed, 29 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/4 diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..85d66bf 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->calc_egprs_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3c92768 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,9 @@ int release(); int abort(); + /* EGPRS: window size calculation function */ + void calc_egprs_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 489020b..c0f37e1 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -1322,3 +1322,27 @@ /* Non SPB cases 0 is reurned */ return EGPRS_RLCMAC_DL_NO_RETX; } + +/* + * This function calculates the DL window size + * for EGPRS. + */ +void gprs_rlcmac_dl_tbf::calc_egprs_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 10:57:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 10:57:20 +0000 Subject: osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Patch Set 4: (3 comments) Still found some cosmetic details, sorry for not spotting them earlier... https://gerrit.osmocom.org/#/c/832/4/src/tbf.h File src/tbf.h: Line 375: /* EGPRS: window size calculation function */ obsolete comment. Any comment that is 1:1 the function name should rather be omitted. Line 376: void calc_egprs_window_size(); usually the naming should be ordered _ so I'd put 'egprs_' in front. https://gerrit.osmocom.org/#/c/832/4/src/tbf_dl.cpp File src/tbf_dl.cpp: Line 1328: * for EGPRS. obsolete comment -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:01:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:01:28 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/798/5/src/tbf.cpp File src/tbf.cpp: Line 381: rather drop the blank line -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:06:05 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:06:05 +0000 Subject: [PATCH] osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/832 to look at the new patch set (#5). tbf_dl: factor out EGPRS DL window size calculation A subsequent patch needs to call this from gprs_rlcmac_tbf::update(), so to avoid code dup, put the calculation in a separate function. Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h M src/tbf_dl.cpp 3 files changed, 28 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/5 diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..cbc0710 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->egprs_calc_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3a6f42d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,8 @@ int release(); int abort(); + void egprs_calc_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 489020b..233cf14 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -1322,3 +1322,27 @@ /* Non SPB cases 0 is reurned */ return EGPRS_RLCMAC_DL_NO_RETX; } + +/* + * This function calculates the DL window size + * for EGPRS. + */ +void gprs_rlcmac_dl_tbf::egprs_calc_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:07:14 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:07:14 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#6). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 10 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/6 diff --git a/src/tbf.cpp b/src/tbf.cpp index 85d66bf..84c8718 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,12 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + if (dl_tbf) + dl_tbf->egprs_calc_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..ea6dcdd 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..d5e8cfa 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:11:05 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:11:05 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 6: (1 comment) https://gerrit.osmocom.org/#/c/798/5/src/tbf.cpp File src/tbf.cpp: Line 381: if (dl_tbf) > rather drop the blank line Done -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:11:37 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:11:37 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#7). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 10 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/7 diff --git a/src/tbf.cpp b/src/tbf.cpp index 85d66bf..e1582c8 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,12 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + if (dl_tbf) + dl_tbf->calc_egprs_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..ea6dcdd 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..d5e8cfa 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:12:59 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:12:59 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding In-Reply-To: References: Message-ID: Patch Set 1: (2 comments) https://gerrit.osmocom.org/#/c/825/4//COMMIT_MSG Commit Message: Line 7: EGPRS: add test case to show LI decoding "... to show LI decoding bug" https://gerrit.osmocom.org/#/c/825/4/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 1913: bts->trx[0].pdch[4].enable(); still the readability issue with very long names repeating -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:15:59 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:15:59 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#5). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 288 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/5 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..b7988a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * Need to add assert for index 1 + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..d41d3c2 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1868,6 +1868,159 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:23:08 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:23:08 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#6). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 290 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/6 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..b7988a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * Need to add assert for index 1 + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..376d242 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -619,6 +619,126 @@ &ulreq, tbf->poll_fn); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + presreq->MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts, uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) @@ -1868,6 +1988,41 @@ printf("=== end %s ===\n", __func__); } +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2700,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:26:21 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:26:21 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 23: ok, good to see that it's on purpose. Maybe a comment would be good for the next guy wondering? -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 23 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:26:49 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:26:49 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 6: (1 comment) https://gerrit.osmocom.org/#/c/825/6/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 622: static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, move this function down. -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:28:23 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:28:23 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#7). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 290 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/7 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..b7988a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,31 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * Need to add assert for index 1 + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index ca5a3c8..2ba77da 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1868,6 +1868,161 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + presreq->MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + presreq->MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2545,6 +2700,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 67aade9..aceb9b4 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6384,3 +6384,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:33:54 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:33:54 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 8: (3 comments) minor details, sorry to not have spotted earlier https://gerrit.osmocom.org/#/c/430/8/src/bts.cpp File src/bts.cpp: Line 520: /* set class to 0,as we don't know the multislot (not really necessary to modify the comment like this and introduce a whitespace error at the same time) Line 591: ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || here you indent once within the if ( ) condition, below you indent twice. Please check what style is used in the surrounding code and stick to that. Line 616: (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { (two indents here, only one above) -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:39:43 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:39:43 +0000 Subject: [PATCH] osmo-pcu[master]: DL TS allocation: add test case to show TS allocation bug fo... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/818 to look at the new patch set (#4). DL TS allocation: add test case to show TS allocation bug for 2nd DL TBF This patch adds a test case test_2_consecutive_dl_tbfs which expects a current bug with TS allocation for 2nd DL TBF. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1792 Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 --- M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 2 files changed, 54 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/18/818/4 diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index b636b6e..f7794f7 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -792,6 +792,56 @@ test_many_connections(alloc_algorithm_dynamic, 160, "algorithm dynamic"); } +static void test_2_consecutive_dl_tbfs() +{ + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + gprs_rlcmac_tbf *dl_tbf1, *dl_tbf2; + uint8_t numTs1 = 0, numTs2 = 0; + + printf("Testing DL TS allocation for Multi UEs\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[4].enable(); + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf1); + + for (int i = 0; i < 8; i++) { + if (dl_tbf1->pdch[i]) + numTs1++; + } + OSMO_ASSERT(numTs1 == 4); + printf("TBF1: numTs(%d)\n", numTs1); + + dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf2); + + for (int i = 0; i < 8; i++) { + if (dl_tbf2->pdch[i]) + numTs2++; + } + + /* + * TODO: currently 2nd DL TBF gets 3 TS + * This behaviour will be fixed in subsequent patch + */ + printf("TBF2: numTs(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 3); + + tbf_free(dl_tbf1); + tbf_free(dl_tbf2); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -809,6 +859,7 @@ test_alloc_b(); test_successive_allocation(); test_many_connections(); + test_2_consecutive_dl_tbfs(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 9f88186..cbb65aa 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10793,3 +10793,6 @@ TBF[31] class 14 reserves ......C. TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs +Testing DL TS allocation for Multi UEs +TBF1: numTs(4) +TBF2: numTs(3) -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:39:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:39:51 +0000 Subject: osmo-pcu[master]: DL TS allocation: add test case to show TS allocation bug fo... In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:45:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 14 Sep 2016 11:45:11 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 7: I would appreciate less noise in the patch submissions, i.e. if you resolve numerous issues, it would be preferable to not submit a new patch set for every single change, but submit all in one fell swoop. i.e. work on your patch and test in your local git repos until you have addressed all comments, and only then re-submit to gerrit. -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 11:55:32 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 11:55:32 +0000 Subject: [MERGED] osmo-pcu[master]: DL TS allocation: add test case to show TS allocation bug fo... In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: DL TS allocation: add test case to show TS allocation bug for 2nd DL TBF ...................................................................... DL TS allocation: add test case to show TS allocation bug for 2nd DL TBF This patch adds a test case test_2_consecutive_dl_tbfs which expects a current bug with TS allocation for 2nd DL TBF. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1792 Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 --- M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 2 files changed, 54 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index b636b6e..f7794f7 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -792,6 +792,56 @@ test_many_connections(alloc_algorithm_dynamic, 160, "algorithm dynamic"); } +static void test_2_consecutive_dl_tbfs() +{ + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + gprs_rlcmac_tbf *dl_tbf1, *dl_tbf2; + uint8_t numTs1 = 0, numTs2 = 0; + + printf("Testing DL TS allocation for Multi UEs\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[4].enable(); + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf1); + + for (int i = 0; i < 8; i++) { + if (dl_tbf1->pdch[i]) + numTs1++; + } + OSMO_ASSERT(numTs1 == 4); + printf("TBF1: numTs(%d)\n", numTs1); + + dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0); + OSMO_ASSERT(dl_tbf2); + + for (int i = 0; i < 8; i++) { + if (dl_tbf2->pdch[i]) + numTs2++; + } + + /* + * TODO: currently 2nd DL TBF gets 3 TS + * This behaviour will be fixed in subsequent patch + */ + printf("TBF2: numTs(%d)\n", numTs2); + OSMO_ASSERT(numTs2 == 3); + + tbf_free(dl_tbf1); + tbf_free(dl_tbf2); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -809,6 +859,7 @@ test_alloc_b(); test_successive_allocation(); test_many_connections(); + test_2_consecutive_dl_tbfs(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 9f88186..cbb65aa 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10793,3 +10793,6 @@ TBF[31] class 14 reserves ......C. TBF[31] class 15 reserves .......C Successfully allocated 160 TBFs +Testing DL TS allocation for Multi UEs +TBF1: numTs(4) +TBF2: numTs(3) -- To view, visit https://gerrit.osmocom.org/818 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I890e4fbb2b64037e051433e70082a197e2a929a6 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 12:15:33 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 12:15:33 +0000 Subject: [PATCH] osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/832 to look at the new patch set (#6). tbf_dl: factor out EGPRS DL window size calculation A subsequent patch needs to call this from gprs_rlcmac_tbf::update(), so to avoid code dup, put the calculation in a separate function. Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h M src/tbf_dl.cpp 3 files changed, 24 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/32/832/6 diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..cbc0710 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->egprs_calc_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3a6f42d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,8 @@ int release(); int abort(); + void egprs_calc_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 489020b..457f2c9 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -1322,3 +1322,23 @@ /* Non SPB cases 0 is reurned */ return EGPRS_RLCMAC_DL_NO_RETX; } + +void gprs_rlcmac_dl_tbf::egprs_calc_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 12:15:33 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 12:15:33 +0000 Subject: [PATCH] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/798 to look at the new patch set (#8). Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 10 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/798/8 diff --git a/src/tbf.cpp b/src/tbf.cpp index cbc0710..97696cb 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,12 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + if (dl_tbf) + dl_tbf->egprs_calc_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..ea6dcdd 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..d5e8cfa 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 12:29:10 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Wed, 14 Sep 2016 12:29:10 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Hello Max, Neels Hofmeyr, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/416 to look at the new patch set (#24). EGPRS: Add EPDAN CRBB Tree based decoding Implemented tree based algorithm to decode compressed bitmap in EPDAN as described in section 9.1.10 of 3GPP 44.060. This algorithm intends to improve the performance over existing method. New Regression test is added under bitcomp directory. Test case is added to validate decompressed result of the bitmap Present in EPDAN. Test is done for multiple bitmaps of varying length. Invalid inputs are also part of the test vector. Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce --- M src/Makefile.am M src/decoding.cpp A src/egprs_rlc_compression.cpp A src/egprs_rlc_compression.h M tests/Makefile.am A tests/bitcomp/BitcompTest.cpp A tests/bitcomp/BitcompTest.err A tests/bitcomp/BitcompTest.ok M tests/testsuite.at 9 files changed, 785 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/16/416/24 diff --git a/src/Makefile.am b/src/Makefile.am index 9bdec2f..9b047e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,7 +62,8 @@ rlc.cpp \ osmobts_sock.cpp \ gprs_codel.c \ - gprs_coding_scheme.cpp + gprs_coding_scheme.cpp \ + egprs_rlc_compression.cpp bin_PROGRAMS = \ osmo-pcu @@ -94,7 +95,8 @@ pcu_utils.h \ cxx_linuxlist.h \ gprs_codel.h \ - gprs_coding_scheme.h + gprs_coding_scheme.h \ + egprs_rlc_compression.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..60ebc0d 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -20,6 +20,7 @@ #include #include #include +#include extern "C" { #include @@ -695,21 +696,17 @@ if (crbb_len > 0) { int old_len = bits->cur_bit; - struct bitvec crbb; - crbb.data = (uint8_t *)desc->CRBB; - crbb.data_len = sizeof(desc->CRBB); - crbb.cur_bit = desc->CRBB_LENGTH; - - rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE, - bits); - + LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exist, " + "CRBB LEN =%d and Starting color code =%d", + desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE); + rc = decompress_crbb(desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE, + desc->CRBB, bits); if (rc < 0) { LOGP(DRLCMACUL, LOGL_NOTICE, - "Failed to decode CRBB: " - "length %d, data '%s'\n", - desc->CRBB_LENGTH, - osmo_hexdump(crbb.data, crbb.data_len)); + "Failed to decode CRBB: length %d, data '%s'\n", + desc->CRBB_LENGTH, osmo_hexdump( + desc->CRBB, (desc->CRBB_LENGTH + 7)/8)); /* We don't know the SSN offset for the URBB, * return what we have so far and assume the * bitmap has stopped here */ diff --git a/src/egprs_rlc_compression.cpp b/src/egprs_rlc_compression.cpp new file mode 100644 index 0000000..4a1f598 --- /dev/null +++ b/src/egprs_rlc_compression.cpp @@ -0,0 +1,337 @@ +/* egprs_rlc_compression.h +* Routines for EGPRS RLC bitmap compression handling +*/ +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +extern void *tall_pcu_ctx; +extern const char *one_run_len_code_list[MAX_CDWDTBL_LEN]; +extern const char *zero_run_len_code_list[MAX_CDWDTBL_LEN]; + +egprs_compress *egprs_compress::s_instance = 0; + +/* Function to create tree node */ +Node *egprs_compress::create_tree_node(void *parent) +{ + Node *new_node; + + new_node = talloc_zero(parent, Node); + new_node->left = NULL; + new_node->right = NULL; + new_node->run_length = -1; + return new_node; +} + +/* Function to build the codeword tree + * \param root[in] Root of Ones or Zeros tree + * \param cdwd[in] Code word + */ +void egprs_compress::build_codeword(Node *root, const char *cdwd[]) +{ + Node *iter; + int len; + int i; + int idx; + + for (idx = 0; idx < MAX_CDWDTBL_LEN; idx++) { + len = strlen((const char *)cdwd[idx]); + iter = root; + for (i = 0; i < len; i++) { + if (cdwd[idx][i] == '0') { + if (!iter->left) + iter->left = create_tree_node(root); + iter = iter->left; + } else if (cdwd[idx][i] == '1') { + if (!iter->right) + iter->right = create_tree_node(root); + iter = iter->right; + } + } + if (iter) { + if (idx < 64) + (iter->run_length) = idx; + else + (iter->run_length) = (idx - 63) * 64; + } + } +} + +const char *one_run_len_code_list[MAX_CDWDTBL_LEN] = { + "00110101", + "000111", + "0111", + "1000", + "1011", + "1100", + "1110", + "1111", + "10011", + "10100", + "00111", + "01000", + "001000", + "000011", + "110100", + "110101", + "101010", + "101011", + "0100111", + "0001100", + "0001000", + "0010111", + "0000011", + "0000100", + "0101000", + "0101011", + "0010011", + "0100100", + "0011000", + "00000010", + "00000011", + "00011010", + "00011011", + "00010010", + "00010011", + "00010100", + "00010101", + "00010110", + "00010111", + "00101000", + "00101001", + "00101010", + "00101011", + "00101100", + "00101101", + "00000100", + "00000101", + "00001010", + "00001011", + "01010010", + "01010011", + "01010100", + "01010101", + "00100100", + "00100101", + "01011000", + "01011001", + "01011010", + "01011011", + "01001010", + "01001011", + "00110010", + "00110011", + "00110100", + "11011", + "10010", + "010111", + "0110111", + "00110110", + "00110111", + "01100100", + "01100101", + "01101000", + "01100111", + "011001100", + "011001101", + "011010010", + "011010011", + "011010100" +}; + +const char *zero_run_len_code_list[MAX_CDWDTBL_LEN] = { + "0000110111", + "10", + "11", + "010", + "011", + "0011", + "0010", + "00011", + "000101", + "000100", + "0000100", + "0000101", + "0000111", + "00000100", + "00000111", + "000011000", + "0000010111", + "0000011000", + "0000001000", + "00001100111", + "00001101000", + "00001101100", + "00000110111", + "00000101000", + "00000010111", + "00000011000", + "000011001010", + "000011001011", + "000011001100", + "000011001101", + "000001101000", + "000001101001", + "000001101010", + "000001101011", + "000011010010", + "000011010011", + "000011010100", + "000011010101", + "000011010110", + "000011010111", + "000001101100", + "000001101101", + "000011011010", + "000011011011", + "000001010100", + "000001010101", + "000001010110", + "000001010111", + "000001100100", + "000001100101", + "000001010010", + "000001010011", + "000000100100", + "000000110111", + "000000111000", + "000000100111", + "000000101000", + "000001011000", + "000001011001", + "000000101011", + "000000101100", + "000001011010", + "000001100110", + "000001100111", + "0000001111", + "000011001000", + "000011001001", + "000001011011", + "000000110011", + "000000110100", + "000000110101", + "0000001101100", + "0000001101101", + "0000001001010", + "0000001001011", + "0000001001100", + "0000001001101", + "0000001110010", + "0000001110011" +}; + +/* search_runlen function will return the runlength for the codeword + * \param root[in] Root of Ones or Zeros tree + * \param bmbuf[in] Recevied compressed bitmap buf + * \param bit_pos[in] The start bit pos to read codeword + * \param len_codewd[in] Length of code word + * \param rlen[out] Run length value + */ +static int search_runlen( + Node *root, + const uint8_t *bmbuf, + uint8_t bit_pos, + uint8_t *len_codewd, + uint16_t *rlen) +{ + Node *iter; + uint8_t dir; + + iter = root; + *len_codewd = 0; + + while (iter->run_length == -1) { + if ((!iter->left) && (!iter->right)) + return -1; + /* get the bit value at the bitpos and put it in right most of dir */ + dir = ((bmbuf[BITS_TO_BYTES(bit_pos)-1] + >>(7-(MOD8(bit_pos)))) & 0x01); + (bit_pos)++; + (*len_codewd)++; + if (((dir&0x01) == 0) && (iter->left != NULL)) + iter = iter->left; + else if (((dir&0x01) == 1) && (iter->right != NULL)) + iter = iter->right; + else + return -1; + } + LOGP(DRLCMACUL, LOGL_DEBUG, "Run_length = %d\n", iter->run_length); + (*rlen) = (iter->run_length); + return 1; +} + +/* Function to decompress crbb + * \param compress_bmap_len[in] Compressed bitmap length + * \param clr_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength + * \param orig_crbb_buf[in] Received block crbb bitmap + * \param dest[out] Uncompressed bitvector + */ +int decompress_crbb( + int8_t compress_bmap_len, + uint8_t clr_code_bit, + const uint8_t *orig_crbb_buf, + bitvec *dest) +{ + + uint8_t bit_pos = 0; + uint8_t data = 0x0; + node *list = NULL; + uint8_t nbits = 0; /* number of bits of codeword */ + uint16_t run_length = 0; + uint16_t cbmaplen = 0; /* compressed bitmap part after decompression */ + unsigned wp = dest->cur_bit; + int rc = 0; + egprs_compress *compress = egprs_compress::instance(); + + while (compress_bmap_len > 0) { + if (clr_code_bit == 1) { + data = 0xff; + list = compress->ones_list; + } else { + data = 0x00; + list = compress->zeros_list; + } + rc = search_runlen(list, orig_crbb_buf, + bit_pos, &nbits, &run_length); + if (rc == -1) + return -1; + /* If run length > 64, need makeup and terminating code */ + if (run_length < 64) + clr_code_bit ? clr_code_bit = 0 : clr_code_bit = 1; + cbmaplen = cbmaplen + run_length; + /* put run length of Ones in uncompressed bitmap */ + while (run_length != 0) { + if (run_length > 8) { + bitvec_write_field(dest, wp, data, 8); + run_length = run_length - 8; + } else { + bitvec_write_field(dest, wp, data, run_length); + run_length = 0; + } + } + bit_pos = bit_pos + nbits; + compress_bmap_len = compress_bmap_len - nbits; + } + return 0; +} + +/* init function to build codeword */ +int egprs_compress::decode_tree_init() +{ + ones_list = create_tree_node(tall_pcu_ctx); + zeros_list = create_tree_node(tall_pcu_ctx); + build_codeword(ones_list, one_run_len_code_list); + build_codeword(zeros_list, zero_run_len_code_list); + return 0; +} diff --git a/src/egprs_rlc_compression.h b/src/egprs_rlc_compression.h new file mode 100644 index 0000000..8d91b2a --- /dev/null +++ b/src/egprs_rlc_compression.h @@ -0,0 +1,50 @@ +/* egprs_rlc_compression.h + * Routines for EGPRS RLC bitmap compression handling + */ + +#pragma once + +#define MAX_CDWDTBL_LEN 79 /* total number of codewords */ +#define BITS_TO_BYTES(X) ((X ? (X/8):0)+1) +#define MOD8(X) (((X)+8) & (0x07)) + +typedef struct node { + struct node *left; + struct node *right; + int run_length; +} Node; + +int decompress_crbb(int8_t compress_bmap_len, uint8_t clr_code_bit, + const uint8_t *orig_buf, bitvec *dest); + +/* Creating singleton class*/ +class egprs_compress +{ +public: + Node *ones_list; + Node *zeros_list; + + int decode_tree_init(void); + + static egprs_compress *instance() + { + if (!s_instance) + s_instance = new egprs_compress; + + return s_instance; + } +private: + static egprs_compress *s_instance; + + egprs_compress() + { + if (decode_tree_init() < 0) { + fprintf(stderr, "Error initializing tree\n"); + exit(1); + } + } + Node *create_tree_node(void *); + void build_codeword(Node *root, const char *cdwd[]); + /* Private because nobody is allow to delete on object of this type */ + ~egprs_compress(); +}; diff --git a/tests/Makefile.am b/tests/Makefile.am index 2a3415e..a24f4ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/ AM_LDFLAGS = -lrt -check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest +check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest noinst_PROGRAMS = emu/pcu_emu rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp @@ -23,6 +23,11 @@ $(top_builddir)/src/libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(COMMON_LA) + +bitcomp_BitcompTest_SOURCES = bitcomp/BitcompTest.cpp ../src/egprs_rlc_compression.cpp +bitcomp_BitcompTest_LDADD = \ $(LIBOSMOCORE_LIBS) \ $(COMMON_LA) @@ -108,6 +113,7 @@ rlcmac/RLCMACTest.ok rlcmac/RLCMACTest.err \ alloc/AllocTest.ok alloc/AllocTest.err \ tbf/TbfTest.ok tbf/TbfTest.err \ + bitcomp/BitcompTest.ok bitcomp/BitcompTest.err \ types/TypesTest.ok types/TypesTest.err \ ms/MsTest.ok ms/MsTest.err \ llc/LlcTest.ok llc/LlcTest.err \ diff --git a/tests/bitcomp/BitcompTest.cpp b/tests/bitcomp/BitcompTest.cpp new file mode 100644 index 0000000..3092872 --- /dev/null +++ b/tests/bitcomp/BitcompTest.cpp @@ -0,0 +1,237 @@ +#include +#include + +#include "rlc.h" +#include "gprs_debug.h" +#include +#include "egprs_rlc_compression.h" + +extern "C" { +#include +#include +#include +#include +} + +#define NEW 1 +#define MASK(n) (0xFF << (8-n)) +#define MAX_CRBB_LEN 23 +#define MAX_URBB_LEN 40 + +void *tall_pcu_ctx; + +struct test_data { + int8_t crbb_len; + uint8_t cc; + uint8_t crbb_data[MAX_CRBB_LEN]; /* compressed data */ + uint8_t ucmp_data[MAX_URBB_LEN]; /* uncompressed data */ + int ucmp_len; + int verify; +} test[] = { + { .crbb_len = 67, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xdb + }, + .ucmp_len = 194, .verify = 1 + }, + { .crbb_len = 40, .cc = 1, + .crbb_data = { + 0x53, 0x06, 0xc5, 0x40, 0x6d + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x03 + }, + .ucmp_len = 182, .verify = 1 + }, + { .crbb_len = 8, .cc = 1, + .crbb_data = {0x02}, + .ucmp_data = {0xff, 0xff, 0xff, 0xf8}, + .ucmp_len = 29, .verify = 1 + }, + { .crbb_len = 103, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03, + 0x71, 0xb0, 0x6e, 0x24 + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff + }, + .ucmp_len = 288, .verify = 1 + }, + /* Test vector from libosmocore test */ + { .crbb_len = 35, .cc = 0, + .crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80}, + .ucmp_data = {0x37, 0x47, 0x81, 0xf0}, + .ucmp_len = 28, .verify = 1 + }, + { .crbb_len = 18, .cc = 1, + .crbb_data = {0xdd, 0x41, 0x00}, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00 + }, + .ucmp_len = 90, .verify = 1 + }, + /*Invalid inputs*/ + { .crbb_len = 18, .cc = 1, + .crbb_data = {0x1E, 0x70, 0xc0}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 14, .cc = 1, + .crbb_data = {0x00, 0x1E, 0x7c}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 24, .cc = 0, + .crbb_data = {0x00, 0x00, 0x00}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + } + }; + +static const struct log_info_cat default_categories[] = { + {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, + {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, + {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1}, + {"DNS", "\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO, 1}, + {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO, 1}, + {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1}, +}; + +static int filter_fn(const struct log_context *ctx, + struct log_target *tar) +{ + return 1; +} + +/* To verify the result with expected result */ +int check_result(bitvec bits, uint8_t *exp_data, int exp_len) +{ + if (bits.cur_bit != exp_len) + return 0; + size_t n = (exp_len / 8); + int rem = (exp_len % 8); + + if (memcmp(exp_data, bits.data, n) == 0) { + if (rem == 0) + return 1; + if ((bits.data[n] & MASK(rem)) == ((*(exp_data + n)) & MASK(rem))) + return 1; + else + return 0; + } else + return 0; +} + +/* To test decoding of compressed bitmap by Tree based method + * and to verify the result with expected result + * for invalid input verfication is suppressed + */ +static void test_EPDAN_decode_tree(void) +{ + bitvec dest; + int init_flag = 1; + int itr; + int rc; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + + printf("=== start %s ===\n", __func__); + + for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) { + dest.data = bits_data; + dest.data_len = sizeof(bits_data); + dest.cur_bit = 0; + memset(dest.data, 0, sizeof(bits_data)); + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTest:%d\nTree based decoding:" + "\nuncompressed data = %s\nlen = %d\n", itr + 1, + osmo_hexdump(test[itr].crbb_data, + (test[itr].crbb_len + 7)/8), test[itr].crbb_len + ); + rc = decompress_crbb(test[itr].crbb_len, test[itr].cc, + test[itr].crbb_data, &dest + ); + if (rc < 0) { + LOGP(DRLCMACUL, LOGL_NOTICE, + "\nFailed to decode CRBB: length %d, data %s", + test[itr].crbb_len, osmo_hexdump( + test[itr].crbb_data, (test[itr].crbb_len + 7)/8)); + } + if (init_flag) + init_flag = 0; + if (test[itr].verify) { + if (check_result(dest, test[itr].ucmp_data, + test[itr].ucmp_len) == 0) { + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTree based decoding" + ":Error\nexpected data = %s\nexpected" + " len = %d\ndecoded data = %s\n" + "decoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + OSMO_ASSERT(0); + } + } + LOGP(DRLCMACDL, LOGL_DEBUG, "\nexpected data = %s\nexpected len = %d" + "\ndecoded data = %s\ndecoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + } + + printf("=== end %s ===\n", __func__); +} + +const struct log_info debug_log_info = { + filter_fn, + (struct log_info_cat *)default_categories, + ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + osmo_init_logging(&debug_log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + + tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context"); + if (!tall_pcu_ctx) + abort(); + + test_EPDAN_decode_tree(); + + if (getenv("TALLOC_REPORT_FULL")) + talloc_report_full(tall_pcu_ctx, stderr); + talloc_free(tall_pcu_ctx); + return EXIT_SUCCESS; +} + +/* + * stubs that should not be reached + */ +extern "C" { +void l1if_pdch_req() { abort(); } +void l1if_connect_pdch() { abort(); } +void l1if_close_pdch() { abort(); } +void l1if_open_pdch() { abort(); } +} + diff --git a/tests/bitcomp/BitcompTest.err b/tests/bitcomp/BitcompTest.err new file mode 100644 index 0000000..7481d72 --- /dev/null +++ b/tests/bitcomp/BitcompTest.err @@ -0,0 +1,132 @@ + +Test:1 +Tree based decoding: +uncompressed data = 02 0c a0 30 cb 1a 0c e3 6c +len = 67 +Run_length = 29 +Run_length = 26 +Run_length = 30 +Run_length = 27 +Run_length = 31 +Run_length = 19 +Run_length = 32 + +expected data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +expected len = 194 +decoded data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +decoded len = 194 + +Test:2 +Tree based decoding: +uncompressed data = 53 06 c5 40 6d +len = 40 +Run_length = 50 +Run_length = 40 +Run_length = 51 +Run_length = 41 + +expected data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +expected len = 182 +decoded data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +decoded len = 182 + +Test:3 +Tree based decoding: +uncompressed data = 02 +len = 8 +Run_length = 29 + +expected data = ff ff ff f8 +expected len = 29 +decoded data = ff ff ff f8 +decoded len = 29 + +Test:4 +Tree based decoding: +uncompressed data = 02 0c e0 41 a0 0c 36 0d 03 71 b0 6e 24 +len = 103 +Run_length = 29 +Run_length = 19 +Run_length = 29 +Run_length = 20 +Run_length = 30 +Run_length = 21 +Run_length = 31 +Run_length = 22 +Run_length = 32 +Run_length = 22 +Run_length = 33 + +expected data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +expected len = 288 +decoded data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +decoded len = 288 + +Test:5 +Tree based decoding: +uncompressed data = de 88 75 65 80 +len = 35 +Run_length = 2 +Run_length = 2 +Run_length = 1 +Run_length = 3 +Run_length = 1 +Run_length = 1 +Run_length = 3 +Run_length = 4 +Run_length = 6 +Run_length = 5 + +expected data = 37 47 81 f0 +expected len = 28 +decoded data = 37 47 81 f0 +decoded len = 28 + +Test:6 +Tree based decoding: +uncompressed data = dd 41 00 +len = 18 +Run_length = 64 +Run_length = 16 +Run_length = 10 + +expected data = ff ff ff ff ff ff ff ff ff ff 00 00 +expected len = 90 +decoded data = ff ff ff ff ff ff ff ff ff ff 00 00 +decoded len = 90 + +Test:7 +Tree based decoding: +uncompressed data = 1e 70 c0 +len = 18 +Run_length = 1 +Run_length = 1 +Run_length = 2 +Run_length = 15 + +expected data = +expected len = 0 +decoded data = +decoded len = 19 + +Test:8 +Tree based decoding: +uncompressed data = 00 1e +len = 14 + +Failed to decode CRBB: length 14, data 00 1e +expected data = +expected len = 0 +decoded data = +decoded len = 0 + +Test:9 +Tree based decoding: +uncompressed data = 00 00 00 +len = 24 + +Failed to decode CRBB: length 24, data 00 00 00 +expected data = +expected len = 0 +decoded data = +decoded len = 0 diff --git a/tests/bitcomp/BitcompTest.ok b/tests/bitcomp/BitcompTest.ok new file mode 100644 index 0000000..f7720fc --- /dev/null +++ b/tests/bitcomp/BitcompTest.ok @@ -0,0 +1,2 @@ +=== start test_EPDAN_decode_tree === +=== end test_EPDAN_decode_tree === diff --git a/tests/testsuite.at b/tests/testsuite.at index 1049b31..e42a0fd 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -23,6 +23,13 @@ AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/tbf/TbfTest], [0], [expout], [experr]) AT_CLEANUP +AT_SETUP([bitcomp]) +AT_KEYWORDS([bitcomp]) +cat $abs_srcdir/bitcomp/BitcompTest.ok > expout +cat $abs_srcdir/bitcomp/BitcompTest.err > experr +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/bitcomp/BitcompTest], [0], [expout], [experr]) +AT_CLEANUP + AT_SETUP([edge]) AT_KEYWORDS([edge]) cat $abs_srcdir/edge/EdgeTest.ok > expout -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin From gerrit-no-reply at lists.osmocom.org Wed Sep 14 12:34:13 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Wed, 14 Sep 2016 12:34:13 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: > ok, good to see that it's on purpose. > Maybe a comment would be good for the next guy wondering? Done. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 14 13:11:48 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 13:11:48 +0000 Subject: osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Patch Set 6: (3 comments) https://gerrit.osmocom.org/#/c/832/4/src/tbf.h File src/tbf.h: Line 375: void egprs_calc_window_size(); > obsolete comment. Any comment that is 1:1 the function name should rather b Done Line 376: > usually the naming should be ordered Done https://gerrit.osmocom.org/#/c/832/4/src/tbf_dl.cpp File src/tbf_dl.cpp: Line 1328: struct gprs_rlcmac_bts *bts_data = bts->bts_data(); > obsolete comment Done -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 13:28:54 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 13:28:54 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#8). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for 3GPP TS 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 287 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/8 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..2a325b5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,32 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 0; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we should see 2 chunks here + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..9f040ff 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 13:29:58 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Wed, 14 Sep 2016 13:29:58 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 8: (2 comments) https://gerrit.osmocom.org/#/c/825/1//COMMIT_MSG Commit Message: Line 11: Release 7 row 4 of Table 10.4.14a.1. > Preferably name it as ETSI TS or 3GPP explicitly with full Done https://gerrit.osmocom.org/#/c/825/1/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 663: Count_MS_RA_capability_value = 1; > You're using ulreq.u.Packet_Resource_Request N times, Done -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 14 14:12:11 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 14 Sep 2016 14:12:11 +0000 Subject: [PATCH] osmo-bts[master]: LC15, SYSMO: Save last SID using common function Message-ID: Review at https://gerrit.osmocom.org/845 LC15, SYSMO: Save last SID using common function The common save_last_sid() function was merged but the corresponding code to use it was somehow lost during transition. Fix it by propagating Fn and calling common function instead of duplicated code. Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Fixes: OS#1800 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 13 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/845/1 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..dcb6ea9 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..41d6989 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -88,7 +88,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..e6fe015 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,7 +200,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -270,14 +270,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..8784938 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..19dd5dc 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -108,7 +108,8 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, + uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..54f2fcd 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,7 +283,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -367,14 +367,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } @@ -394,7 +388,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; uint8_t *l1_payload; @@ -428,7 +422,7 @@ case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + rtp_pl_len, lchan, fn); break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 14 15:17:41 2016 From: gerrit-no-reply at lists.osmocom.org (bhargava_abhyankar) Date: Wed, 14 Sep 2016 15:17:41 +0000 Subject: [PATCH] osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/430 to look at the new patch set (#9). Handle EGPRS 11 bit RACH in osmo-pcu A function is_single_block is added to get request type of RACH. EGPRS 11 bit RACH is handled. Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 --- M src/bts.cpp M src/bts.h 2 files changed, 84 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/30/430/9 diff --git a/src/bts.cpp b/src/bts.cpp index 795baa6..015bf9f 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -480,20 +480,16 @@ uint8_t usf = 7; uint8_t tsc; uint16_t ta; + uint16_t ms_class = 0; + uint16_t priority = 0; rach_frame(); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + if (qta < 0) qta = 0; if (qta > 252) @@ -516,8 +512,16 @@ } else { // Create new TBF #warning "Copy and paste with other routines.." - /* set class to 0, since we don't know the multislot class yet */ - tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + + if (is_11bit) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0, since we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); /* FIXME: send reject */ @@ -565,6 +569,73 @@ return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (!val) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase " + "access but we force two phase " + "access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index 801342d..ba6fc4d 100644 --- a/src/bts.h +++ b/src/bts.h @@ -290,6 +290,8 @@ int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst_type); -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Wed Sep 14 15:37:29 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 14 Sep 2016 15:37:29 +0000 Subject: [PATCH] openbsc[master]: DTX: store time instead of fn Message-ID: Review at https://gerrit.osmocom.org/846 DTX: store time instead of fn As SID needs to be repeated every 160 milliseconds there's no point in storing GSM Fn with it. Store time in milliseconds instead. Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Fixes: OS#1799 --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/46/846/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index ce2e9b7..d50ae84 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -297,7 +297,7 @@ struct { uint8_t buf[16]; uint8_t len; - uint32_t fn; + time_t msec; /* time in milliseconds */ bool is_update; } last_sid; /* set for each SID frame to detect talkspurt for codecs without -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 14 15:53:43 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 14 Sep 2016 15:53:43 +0000 Subject: [PATCH] osmo-bts[master]: lc15, sysmo: fix last SID store/repeat In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/845 to look at the new patch set (#2). lc15, sysmo: fix last SID store/repeat The common save_last_sid() function was merged but the corresponding code to use it was somehow lost during transition. Fix it to work with milliseconds instead of GSM Fn and use fixed function instead of duplicated code. Note: this requires corresponding change in OpenBSC. Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Fixes: OS#1800, #1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 44 insertions(+), 46 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/845/2 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..6784818 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -22,7 +22,8 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); + bool update); +bool check_last_seed(const struct gsm_lchan *lchan); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..903b5a8 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -27,7 +27,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -97,20 +97,49 @@ } } +static inline time_t get_msec() +{ + struct timespec tspec; + clock_gettime(CLOCK_MONOTONIC, &tspec); + + return 1000 * tspec.tv_sec + tspec.tv_nsec / 1000000; +} + /* store the last SID frame in lchan context */ void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) + bool update) { size_t copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); + struct timespec tspec; + clock_gettime(CLOCK_MONOTONIC, &tspec); lchan->tch.last_sid.len = copy_len; - lchan->tch.last_sid.fn = fn; + lchan->tch.last_sid.msec = get_msec(); lchan->tch.last_sid.is_update = update; memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* check if enough time has passed since last SID to warrant repetition */ +bool check_last_seed(const struct gsm_lchan *lchan) +{ + /* Each voice frame is 20 ms */ + time_t msec = get_msec(); + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (msec - lchan->tch.last_sid.msec < 140) + return false; + return true; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (msec - lchan->tch.last_sid.msec < 60) + return false; + return true; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..cb55f6c 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -270,14 +270,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, sti); return payload_len+1; } @@ -512,19 +506,9 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (!check_last_seed(lchan)) { + msgb_free(msg); + return NULL; } if (repeat_last_sid(lchan, msg)) return msg; diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..e2c1545 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -367,14 +367,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, sti); return payload_len+1; } @@ -615,19 +609,9 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (!check_last_seed(lchan)) { + msgb_free(msg); + return NULL; } if (repeat_last_sid(lchan, msg)) return msg; -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 14 22:52:27 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Wed, 14 Sep 2016 22:52:27 +0000 Subject: [PATCH] openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/838 to look at the new patch set (#2). Consistenly format variables in */Makefile.am files Change-Id: Ifa21513c007072314097b7bec188579972dc1694 --- M openbsc/Makefile.am M openbsc/doc/Makefile.am M openbsc/doc/examples/Makefile.am M openbsc/include/Makefile.am M openbsc/include/openbsc/Makefile.am M openbsc/src/Makefile.am M openbsc/src/gprs/Makefile.am M openbsc/src/ipaccess/Makefile.am M openbsc/src/libbsc/Makefile.am M openbsc/src/libcommon/Makefile.am M openbsc/src/libfilter/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/src/libmgcp/Makefile.am M openbsc/src/libmsc/Makefile.am M openbsc/src/libtrau/Makefile.am M openbsc/src/osmo-bsc/Makefile.am M openbsc/src/osmo-bsc_mgcp/Makefile.am M openbsc/src/osmo-bsc_nat/Makefile.am M openbsc/src/osmo-nitb/Makefile.am M openbsc/src/utils/Makefile.am M openbsc/tests/Makefile.am M openbsc/tests/abis/Makefile.am M openbsc/tests/bsc-nat/Makefile.am M openbsc/tests/bsc/Makefile.am M openbsc/tests/channel/Makefile.am M openbsc/tests/db/Makefile.am M openbsc/tests/gbproxy/Makefile.am M openbsc/tests/gsm0408/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mgcp/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/oap/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/smpp/Makefile.am M openbsc/tests/subscr/Makefile.am M openbsc/tests/trau/Makefile.am M openbsc/tests/xid/Makefile.am 37 files changed, 1,478 insertions(+), 461 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/838/2 diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am index 8696eb4..f7eda56 100644 --- a/openbsc/Makefile.am +++ b/openbsc/Makefile.am @@ -1,7 +1,16 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = doc include src tests +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +SUBDIRS = \ + doc \ + include \ + src \ + tests \ + $(NULL) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = openbsc.pc diff --git a/openbsc/doc/Makefile.am b/openbsc/doc/Makefile.am index aee2d7b..5a23107 100644 --- a/openbsc/doc/Makefile.am +++ b/openbsc/doc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = examples +SUBDIRS = \ + examples \ + $(NULL) diff --git a/openbsc/doc/examples/Makefile.am b/openbsc/doc/examples/Makefile.am index 8f14fdc..530c3fa 100644 --- a/openbsc/doc/examples/Makefile.am +++ b/openbsc/doc/examples/Makefile.am @@ -1,4 +1,3 @@ - CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' dist-hook: diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index 4596b6e..3234e62 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,8 @@ -SUBDIRS = openbsc +SUBDIRS = \ + openbsc \ + $(NULL) -noinst_HEADERS = mISDNif.h compat_af_isdn.h +noinst_HEADERS = \ + mISDNif.h \ + compat_af_isdn.h \ + $(NULL) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..d82d0c4 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -1,25 +1,87 @@ -noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ - gsm_subscriber.h gsm_04_11.h debug.h signal.h \ - misdn.h chan_alloc.h paging.h ctrl.h \ - trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ - silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h \ - vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \ - handover_decision.h rrlp.h \ - crc24.h gprs_llc.h gprs_gmm.h \ - gb_proxy.h gprs_sgsn.h sgsn.h \ - auth.h osmo_msc.h bsc_msc.h bsc_nat.h \ - osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \ - osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.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_client.h bsc_msg_filter.h \ - oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ - iu.h +noinst_HEADERS = \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bss.h \ + chan_alloc.h \ + crc24.h \ + ctrl.h \ + db.h \ + debug.h \ + e1_config.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_gsup_client.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp.h \ + gprs_utils.h \ + gsm_04_08.h \ + gsm_04_11.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + gtphub.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ + iu.h + meas_feed.h \ + meas_rep.h \ + mgcp.h \ + mgcp_internal.h \ + mgcp_transcode.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + nat_rewrite_trie.h \ + network_listen.h \ + oap.h \ + oap_messages.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_msc_data.h \ + osmux.h \ + paging.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + smpp.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + token_auth.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + $(NULL) -openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h -openbscdir = $(includedir)/openbsc +openbsc_HEADERS = \ + bsc_api.h \ + gsm_04_08.h \ + meas_rep.h \ + $(NULL) + +openbscdir = \ + $(includedir)/openbsc \ + $(NULL) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 4aa880f..272292a 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -1,22 +1,59 @@ -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) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) # Libraries -SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter +SUBDIRS = \ + libcommon \ + libmgcp \ + libbsc \ + libmsc \ + libtrau \ + libfilter \ + $(NULL) # Conditional Libraries if BUILD_IU -SUBDIRS += libiu +SUBDIRS += \ + libiu \ + $(NULL) endif # Programs -SUBDIRS += osmo-nitb osmo-bsc_mgcp utils ipaccess gprs +SUBDIRS += \ + osmo-nitb \ + osmo-bsc_mgcp \ + utils \ + ipaccess \ + gprs \ + $(NULL) # Conditional Programs if BUILD_NAT -SUBDIRS += osmo-bsc_nat +SUBDIRS += \ + osmo-bsc_nat \ + $(NULL) endif + if BUILD_BSC -SUBDIRS += osmo-bsc +SUBDIRS += \ + osmo-bsc \ + $(NULL) endif diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..6269722 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -1,50 +1,127 @@ -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) \ - $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(NULL) -bin_PROGRAMS = osmo-gbproxy +bin_PROGRAMS = \ + osmo-gbproxy \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -bin_PROGRAMS += osmo-sgsn osmo-gtphub +bin_PROGRAMS += \ + osmo-sgsn \ + osmo-gtphub \ + $(NULL) endif endif -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) $(LIBCRYPTO_LIBS) -lrt +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 \ + $(NULL) +osmo_gbproxy_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) -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_utils.c gprs_gsup_client.c \ - sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +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_utils.c \ + gprs_gsup_client.c \ + sgsn_cdr.c \ + sgsn_ares.c \ + oap.c \ + oap_messages.c \ + gprs_llc_xid.c \ + $(NULL) +osmo_sgsn_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif -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 +osmo_gtphub_SOURCES = \ + gtphub_main.c \ + gtphub.c \ + gtphub_sock.c \ + gtphub_ares.c \ + gtphub_vty.c \ + sgsn_ares.c \ + gprs_utils.c \ + $(NULL) +osmo_gtphub_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCARES_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am index 9acc0f7..64bf249 100644 --- a/openbsc/src/ipaccess/Makefile.am +++ b/openbsc/src/ipaccess/Makefile.am @@ -1,26 +1,65 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = abisip-find ipaccess-config ipaccess-proxy +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -abisip_find_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) -abisip_find_SOURCES = abisip-find.c +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -ipaccess_config_SOURCES = ipaccess-config.c ipaccess-firmware.c network_listen.c +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +bin_PROGRAMS = \ + abisip-find \ + ipaccess-config \ + ipaccess-proxy \ + $(NULL) + +abisip_find_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) + +abisip_find_SOURCES = \ + abisip-find.c \ + $(NULL) + +ipaccess_config_SOURCES = \ + ipaccess-config.c \ + ipaccess-firmware.c \ + network_listen.c \ + $(NULL) # FIXME: resolve the bogus dependencies patched around here: ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBCRYPT) $(OSMO_LIBS) + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(OSMO_LIBS) \ + $(NULL) -ipaccess_proxy_SOURCES = ipaccess-proxy.c -ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) +ipaccess_proxy_SOURCES = \ + ipaccess-proxy.c \ + $(NULL) + +ipaccess_proxy_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am index fd8de0e..ad73d1e 100644 --- a/openbsc/src/libbsc/Makefile.am +++ b/openbsc/src/libbsc/Makefile.am @@ -1,28 +1,52 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libbsc.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libbsc_a_SOURCES = abis_nm.c abis_nm_vty.c \ - abis_om2000.c abis_om2000_vty.c \ - abis_rsl.c bsc_rll.c \ - paging.c \ - bts_ericsson_rbs2000.c \ - bts_ipaccess_nanobts.c \ - bts_siemens_bs11.c \ - bts_nokia_site.c \ - bts_unknown.c \ - bts_sysmobts.c \ - chan_alloc.c \ - handover_decision.c handover_logic.c meas_rep.c \ - rest_octets.c system_information.c \ - e1_config.c \ - bsc_api.c bsc_msc.c bsc_vty.c \ - gsm_04_08_utils.c \ - bsc_init.c bts_init.c bsc_rf_ctrl.c \ - arfcn_range_encode.c bsc_ctrl_commands.c \ - bsc_ctrl_lookup.c \ - net_init.c \ - bsc_dyn_ts.c +noinst_LIBRARIES = \ + libbsc.a \ + $(NULL) + +libbsc_a_SOURCES = abis_nm.c \ + abis_nm_vty.c \ + abis_om2000.c \ + abis_om2000_vty.c \ + abis_rsl.c \ + bsc_rll.c \ + paging.c \ + bts_ericsson_rbs2000.c \ + bts_ipaccess_nanobts.c \ + bts_siemens_bs11.c \ + bts_nokia_site.c \ + bts_unknown.c \ + bts_sysmobts.c \ + chan_alloc.c \ + handover_decision.c \ + handover_logic.c \ + meas_rep.c \ + rest_octets.c \ + system_information.c \ + e1_config.c \ + bsc_api.c \ + bsc_msc.c bsc_vty.c \ + gsm_04_08_utils.c \ + bsc_init.c \ + bts_init.c \ + bsc_rf_ctrl.c \ + arfcn_range_encode.c \ + bsc_ctrl_commands.c \ + bsc_ctrl_lookup.c \ + net_init.c \ + bsc_dyn_ts.c \ + $(NULL) diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am index 75f40ee..6cfebc2 100644 --- a/openbsc/src/libcommon/Makefile.am +++ b/openbsc/src/libcommon/Makefile.am @@ -1,9 +1,29 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libcommon.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \ - gsm_data_shared.c socket.c talloc_ctx.c \ - gsm_subscriber_base.c +noinst_LIBRARIES = \ + libcommon.a \ + $(NULL) + +libcommon_a_SOURCES = \ + bsc_version.c \ + common_vty.c \ + debug.c \ + gsm_data.c \ + gsm_data_shared.c \ + socket.c \ + talloc_ctx.c \ + gsm_subscriber_base.c \ + $(NULL) diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am index ed3cd43..6d3db0b 100644 --- a/openbsc/src/libfilter/Makefile.am +++ b/openbsc/src/libfilter/Makefile.am @@ -1,11 +1,26 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libfilter.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libfilter.a \ + $(NULL) libfilter_a_SOURCES = \ bsc_msg_filter.c \ bsc_msg_acc.c \ - bsc_msg_vty.c + bsc_msg_vty.c \ + $(NULL) diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..e5f9e27 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,10 +1,28 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libiu.a +noinst_LIBRARIES = \ + libiu.a \ + $(NULL) -libiu_a_SOURCES = iu.c iu_vty.c +libiu_a_SOURCES = \ + iu.c \ + iu_vty.c \ + $(NULL) diff --git a/openbsc/src/libmgcp/Makefile.am b/openbsc/src/libmgcp/Makefile.am index 4403d60..544a795 100644 --- a/openbsc/src/libmgcp/Makefile.am +++ b/openbsc/src/libmgcp/Makefile.am @@ -1,16 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(COVERAGE_LDFLAGS) $(LIBBCG729_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libmgcp.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_HEADERS = g711common.h +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBBCG729_LIBS) \ + $(NULL) -libmgcp_a_SOURCES = mgcp_protocol.c mgcp_network.c mgcp_vty.c mgcp_osmux.c \ - mgcp_sdp.c +noinst_LIBRARIES = \ + libmgcp.a \ + $(NULL) + +noinst_HEADERS = \ + g711common.h \ + $(NULL) + +libmgcp_a_SOURCES = \ + mgcp_protocol.c \ + mgcp_network.c \ + mgcp_vty.c \ + mgcp_osmux.c \ + mgcp_sdp.c \ + $(NULL) if BUILD_MGCP_TRANSCODING - libmgcp_a_SOURCES += mgcp_transcode.c +libmgcp_a_SOURCES += \ + mgcp_transcode.c \ + $(NULL) endif diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index 5195890..ba44d2e 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -1,27 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_feed.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libmsc.a +noinst_HEADERS = \ + meas_feed.h \ + $(NULL) -libmsc_a_SOURCES = auth.c \ - db.c \ - gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c mncc_builtin.c mncc_sock.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - token_auth.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c ctrl_commands.c meas_feed.c +noinst_LIBRARIES = \ + libmsc.a \ + $(NULL) + +libmsc_a_SOURCES = auth.c \ + db.c \ + gsm_04_08.c \ + gsm_04_11.c \ + gsm_04_11_helper.c \ + gsm_04_80.c \ + gsm_subscriber.c \ + mncc.c \ + mncc_builtin.c \ + mncc_sock.c \ + rrlp.c \ + silent_call.c \ + sms_queue.c \ + token_auth.c \ + ussd.c \ + vty_interface_layer3.c \ + transaction.c \ + osmo_msc.c \ + ctrl_commands.c \ + meas_feed.c \ + $(NULL) if BUILD_SMPP -noinst_HEADERS += smpp_smsc.h -libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c +noinst_HEADERS += \ + smpp_smsc.h \ + $(NULL) + +libmsc_a_SOURCES += \ + smpp_smsc.c \ + smpp_openbsc.c \ + smpp_vty.c \ + smpp_utils.c \ + $(NULL) endif diff --git a/openbsc/src/libtrau/Makefile.am b/openbsc/src/libtrau/Makefile.am index 0fe3a53..46becd6 100644 --- a/openbsc/src/libtrau/Makefile.am +++ b/openbsc/src/libtrau/Makefile.am @@ -1,7 +1,31 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libtrau.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libtrau_a_SOURCES = rtp_proxy.c trau_mux.c trau_upqueue.c +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libtrau.a \ + $(NULL) + +libtrau_a_SOURCES = \ + rtp_proxy.c \ + trau_mux.c \ + trau_upqueue.c \ + $(NULL) diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 4aa1803..b6e7638 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -1,21 +1,56 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc \ + $(NULL) -osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ - osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c +osmo_bsc_SOURCES = \ + osmo_bsc_main.c \ + osmo_bsc_vty.c \ + osmo_bsc_api.c \ + osmo_bsc_grace.c \ + osmo_bsc_msc.c \ + osmo_bsc_sccp.c \ + osmo_bsc_filter.c \ + osmo_bsc_bssap.c \ + osmo_bsc_audio.c \ + osmo_bsc_ctrl.c \ + $(NULL) + # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_mgcp/Makefile.am b/openbsc/src/osmo-bsc_mgcp/Makefile.am index a48f24b..d850be7 100644 --- a/openbsc/src/osmo-bsc_mgcp/Makefile.am +++ b/openbsc/src/osmo-bsc_mgcp/Makefile.am @@ -1,14 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_mgcp +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -osmo_bsc_mgcp_SOURCES = mgcp_main.c +bin_PROGRAMS = \ + osmo-bsc_mgcp \ + $(NULL) + +osmo_bsc_mgcp_SOURCES = \ + mgcp_main.c \ + $(NULL) osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libmgcp/libmgcp.a -lrt \ - $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(LIBBCG729_LIBS) \ - $(LIBRARY_GSM) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_nat/Makefile.am b/openbsc/src/osmo-bsc_nat/Makefile.am index 4a6f74d..2952b4f 100644 --- a/openbsc/src/osmo-bsc_nat/Makefile.am +++ b/openbsc/src/osmo-bsc_nat/Makefile.am @@ -1,19 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBCRYPTO_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_nat +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc_nat \ + $(NULL) -osmo_bsc_nat_SOURCES = bsc_filter.c bsc_mgcp_utils.c bsc_nat.c bsc_nat_utils.c \ - bsc_nat_vty.c bsc_sccp.c bsc_ussd.c bsc_nat_ctrl.c \ - bsc_nat_rewrite.c bsc_nat_rewrite_trie.c bsc_nat_filter.c +osmo_bsc_nat_SOURCES = \ + bsc_filter.c \ + bsc_mgcp_utils.c \ + bsc_nat.c \ + bsc_nat_utils.c \ + bsc_nat_vty.c \ + bsc_sccp.c \ + bsc_ussd.c \ + bsc_nat_ctrl.c \ + bsc_nat_rewrite.c \ + bsc_nat_rewrite_trie.c \ + bsc_nat_filter.c \ + $(NULL) + osmo_bsc_nat_LDADD = \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libfilter/libfilter.a \ - -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-nitb/Makefile.am b/openbsc/src/osmo-nitb/Makefile.am index 3b7cc8d..60514c0 100644 --- a/openbsc/src/osmo-nitb/Makefile.am +++ b/openbsc/src/osmo-nitb/Makefile.am @@ -1,18 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = osmo-nitb +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_nitb_SOURCES = bsc_hack.c +bin_PROGRAMS = \ + osmo-nitb \ + $(NULL) + +osmo_nitb_SOURCES = \ + bsc_hack.c \ + $(NULL) + osmo_nitb_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - -ldbi $(LIBCRYPT) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOABIS_LIBS) $(LIBSMPP34_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..fbeb8ed 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,42 +1,124 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ - $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_db.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = bs11_config isdnsync +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + meas_db.h \ + $(NULL) + +bin_PROGRAMS = \ + bs11_config \ + isdnsync \ + $(NULL) + if HAVE_SQLITE3 -bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db +bin_PROGRAMS += \ + osmo-meas-pcap2db \ + osmo-meas-udp2db \ + $(NULL) endif if HAVE_LIBCDK -bin_PROGRAMS += meas_vis +bin_PROGRAMS += \ + meas_vis \ + $(NULL) endif if BUILD_SMPP -noinst_PROGRAMS = smpp_mirror +noinst_PROGRAMS = \ + smpp_mirror \ + $(NULL) endif -bs11_config_SOURCES = bs11_config.c -bs11_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +bs11_config_SOURCES = \ + bs11_config.c \ + $(NULL) -isdnsync_SOURCES = isdnsync.c +bs11_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) -smpp_mirror_SOURCES = smpp_mirror.c -smpp_mirror_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) +isdnsync_SOURCES = \ + isdnsync.c \ + $(NULL) -meas_vis_SOURCES = meas_vis.c -meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses -meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_SOURCES = \ + smpp_mirror.c \ + $(NULL) -osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c -osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS) -osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(NULL) -osmo_meas_udp2db_SOURCES = meas_udp2db.c meas_db.c -osmo_meas_udp2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(SQLITE3_LIBS) -osmo_meas_udp2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_SOURCES = \ + meas_vis.c \ + $(NULL) + +meas_vis_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lcdk \ + -lncurses \ + $(NULL) + +meas_vis_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_pcap2db_SOURCES = \ + meas_pcap2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_pcap2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + -lpcap \ + $(NULL) + +osmo_meas_pcap2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_udp2db_SOURCES = \ + meas_udp2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_udp2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +osmo_meas_udp2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..b069dff 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,21 +1,46 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid +SUBDIRS = \ + gsm0408 \ + db \ + channel \ + mgcp \ + gprs \ + abis \ + gbproxy \ + trau \ + subscr \ + mm_auth \ + xid \ + $(NULL) if BUILD_NAT -SUBDIRS += bsc-nat bsc-nat-trie +SUBDIRS += \ + bsc-nat \ + bsc-nat-trie \ + $(NULL) endif if BUILD_BSC -SUBDIRS += bsc +SUBDIRS += \ + bsc \ + $(NULL) endif if BUILD_SMPP -SUBDIRS += smpp +SUBDIRS += \ + smpp \ + $(NULL) endif if HAVE_LIBGTP -SUBDIRS += gtphub +SUBDIRS += \ + gtphub \ + $(NULL) + if HAVE_LIBCARES -SUBDIRS += sgsn oap +SUBDIRS += \ + sgsn \ + oap \ + $(NULL) endif endif @@ -38,9 +63,20 @@ echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) vty_test_runner.py ctrl_test_runner.py smpp_test_runner.py +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + vty_test_runner.py \ + ctrl_test_runner.py \ + smpp_test_runner.py \ + $(NULL) + TESTSUITE = $(srcdir)/testsuite -DISTCLEANFILES = atconfig + +DISTCLEANFILES = \ + atconfig \ + $(NULL) if ENABLE_EXT_TESTS python-tests: $(BUILT_SOURCES) diff --git a/openbsc/tests/abis/Makefile.am b/openbsc/tests/abis/Makefile.am index c2e38de..cbc3e07 100644 --- a/openbsc/tests/abis/Makefile.am +++ b/openbsc/tests/abis/Makefile.am @@ -1,17 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = abis_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = abis_test +EXTRA_DIST = \ + abis_test.ok \ + $(NULL) -abis_test_SOURCES = abis_test.c +noinst_PROGRAMS = \ + abis_test \ + $(NULL) + +abis_test_SOURCES = \ + abis_test.c \ + $(NULL) abis_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 26e5500..fa55d27 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -1,26 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_nat_test.ok bsc_data.c barr.cfg barr_dup.cfg prefixes.csv +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_nat_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_nat_test_SOURCES = bsc_nat_test.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c +EXTRA_DIST = \ + bsc_nat_test.ok \ + bsc_data.c \ + barr.cfg \ + barr_dup.cfg \ + prefixes.csv \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_nat_test \ + $(NULL) + +bsc_nat_test_SOURCES = \ + bsc_nat_test.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c + bsc_nat_test_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) \ - $(LIBOSMOCTRL_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am index 8b786ff..ddfa437 100644 --- a/openbsc/tests/bsc/Makefile.am +++ b/openbsc/tests/bsc/Makefile.am @@ -1,18 +1,45 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_test_SOURCES = bsc_test.c \ - $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c -bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) +EXTRA_DIST = \ + bsc_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_test \ + $(NULL) + +bsc_test_SOURCES = \ + bsc_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(NULL) + +bsc_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am index 51b2f83..a94e853 100644 --- a/openbsc/tests/channel/Makefile.am +++ b/openbsc/tests/channel/Makefile.am @@ -1,14 +1,33 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = channel_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = channel_test +EXTRA_DIST = \ + channel_test.ok \ + $(NULL) -channel_test_SOURCES = channel_test.c +noinst_PROGRAMS = \ + channel_test \ + $(NULL) + +channel_test_SOURCES = \ + channel_test.c \ + $(NULL) channel_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ - -ldbi $(LIBOSMOGSM_LIBS) $(LIBCRYPTO_LIBS) + $(LIBOSMOGSM_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am index be3af5f..9ba6b1b 100644 --- a/openbsc/tests/db/Makefile.am +++ b/openbsc/tests/db/Makefile.am @@ -1,17 +1,48 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = db_test.ok db_test.err hlr.sqlite3 +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = db_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -db_test_SOURCES = db_test.c -db_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBCRYPTO_LIBS) -ldbi +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + hlr.sqlite3 \ + $(NULL) + +noinst_PROGRAMS = \ + db_test \ + $(NULL) + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gbproxy/Makefile.am b/openbsc/tests/gbproxy/Makefile.am index 18d77a8..2dd66df 100644 --- a/openbsc/tests/gbproxy/Makefile.am +++ b/openbsc/tests/gbproxy/Makefile.am @@ -1,27 +1,54 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gbproxy_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = gbproxy_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -gbproxy_test_SOURCES = gbproxy_test.c +EXTRA_DIST = \ + gbproxy_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + gbproxy_test \ + $(NULL) + +gbproxy_test_SOURCES = \ + gbproxy_test.c \ + $(NULL) + gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes + -Wl,--wrap=RAND_bytes \ + $(NULL) + gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) -lrt + $(top_builddir)/src/gprs/gb_proxy.o \ + $(top_builddir)/src/gprs/gb_proxy_patch.o \ + $(top_builddir)/src/gprs/gb_proxy_peer.o \ + $(top_builddir)/src/gprs/gb_proxy_tlli.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBRARY_DL) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index 79fb9f1..11fa6b9 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -1,12 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -noinst_PROGRAMS = gsm0408_test +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gsm0408_test.ok +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -gsm0408_test_SOURCES = gsm0408_test.c -gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) -ldbi +noinst_PROGRAMS = \ + gsm0408_test \ + $(NULL) + +EXTRA_DIST = \ + gsm0408_test.ok \ + $(NULL) + +gsm0408_test_SOURCES = \ + gsm0408_test.c \ + $(NULL) + +gsm0408_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..137924d 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,24 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) EXTRA_DIST = \ - gtphub_test.ok + gtphub_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = gtphub_test +noinst_PROGRAMS = \ + gtphub_test \ + $(NULL) endif endif -gtphub_test_SOURCES = gtphub_test.c +gtphub_test_SOURCES = \ + gtphub_test.c \ + $(NULL) + gtphub_test_LDFLAGS = \ -Wl,--wrap=gtphub_resolve_ggsn_addr \ -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write + -Wl,--wrap=gtphub_write \ + $(NULL) gtphub_test_LDADD = \ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt - + -lgtp \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 82d6ac6..4e7a558 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -1,30 +1,73 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_FLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir) \ + $(NULL) -EXTRA_DIST = mgcp_test.ok mgcp_transcoding_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_FLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = mgcp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + mgcp_test.ok \ + mgcp_transcoding_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + mgcp_test \ + $(NULL) if BUILD_MGCP_TRANSCODING -noinst_PROGRAMS += mgcp_transcoding_test +noinst_PROGRAMS += \ + mgcp_transcoding_test \ + $(NULL) endif -mgcp_test_SOURCES = mgcp_test.c +mgcp_test_SOURCES = \ + mgcp_test.c \ + $(NULL) -mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) +mgcp_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + -lrt \ + -lm \ + $(NULL) -mgcp_transcoding_test_SOURCES = mgcp_transcoding_test.c +mgcp_transcoding_test_SOURCES = \ + mgcp_transcoding_test.c \ + $(NULL) mgcp_transcoding_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBBCG729_LIBS) -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) $(LIBRARY_GSM) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + -lm \ + $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..7eb14fa 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -1,21 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -noinst_PROGRAMS = mm_auth_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(NULL) -EXTRA_DIST = mm_auth_test.ok +noinst_PROGRAMS = \ + mm_auth_test \ + $(NULL) -mm_auth_test_SOURCES = mm_auth_test.c +EXTRA_DIST = \ + mm_auth_test.ok \ + $(NULL) + +mm_auth_test_SOURCES = \ + mm_auth_test.c \ + $(NULL) mm_auth_test_LDFLAGS = \ -Wl,--wrap=db_get_authinfo_for_subscr \ -Wl,--wrap=db_get_lastauthtuple_for_subscr \ - -Wl,--wrap=db_sync_lastauthtuple_for_subscr + -Wl,--wrap=db_sync_lastauthtuple_for_subscr \ + $(NULL) -mm_auth_test_LDADD = $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) +mm_auth_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/oap/Makefile.am b/openbsc/tests/oap/Makefile.am index 538e178..06ccf33 100644 --- a/openbsc/tests/oap/Makefile.am +++ b/openbsc/tests/oap/Makefile.am @@ -1,15 +1,30 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = oap_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + oap_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = oap_test +noinst_PROGRAMS = \ + oap_test \ + $(NULL) endif endif -oap_test_SOURCES = oap_test.c +oap_test_SOURCES = \ + oap_test.c \ + $(NULL) oap_test_LDADD = \ $(top_builddir)/src/gprs/oap.o \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..1887861 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,20 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) + if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -EXTRA_DIST = sgsn_test.ok +EXTRA_DIST = \ + sgsn_test.ok \ + $(NULL) -noinst_PROGRAMS = sgsn_test +noinst_PROGRAMS = \ + sgsn_test \ + $(NULL) -sgsn_test_SOURCES = sgsn_test.c +sgsn_test_SOURCES = \ + sgsn_test.c \ + $(NULL) + sgsn_test_LDFLAGS = \ -Wl,--wrap=RAND_bytes \ -Wl,--wrap=sgsn_update_subscriber_data \ -Wl,--wrap=gprs_subscr_request_update_location \ -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gprs_gsup_client_send + -Wl,--wrap=gprs_gsup_client_send \ + $(NULL) sgsn_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_parse.o \ @@ -33,7 +56,7 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -41,12 +64,15 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + -lgtp \ + -lrt \ + $(NULL) + if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) + $(LIBASN1C_LIBS) \ + $(NULL) endif - diff --git a/openbsc/tests/smpp/Makefile.am b/openbsc/tests/smpp/Makefile.am index aab4de9..5082707 100644 --- a/openbsc/tests/smpp/Makefile.am +++ b/openbsc/tests/smpp/Makefile.am @@ -1,13 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/libmsc \ + $(NULL) -EXTRA_DIST = smpp_test.ok smpp_test.err +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = smpp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -smpp_test_SOURCES = smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c +EXTRA_DIST = \ + smpp_test.ok \ + smpp_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + smpp_test \ + $(NULL) + +smpp_test_SOURCES = \ + smpp_test.c \ + $(top_builddir)/src/libmsc/smpp_utils.c \ + $(NULL) + smpp_test_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/subscr/Makefile.am b/openbsc/tests/subscr/Makefile.am index 4f96dc9..72f97e6 100644 --- a/openbsc/tests/subscr/Makefile.am +++ b/openbsc/tests/subscr/Makefile.am @@ -1,18 +1,42 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = subscr_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = subscr_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -subscr_test_SOURCES = subscr_test.c -subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -# -ldbi +EXTRA_DIST = \ + subscr_test.ok \ + $(NULL) +noinst_PROGRAMS = \ + subscr_test \ + $(NULL) + +subscr_test_SOURCES = \ + subscr_test.c \ + $(NULL) + +subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(NULL) diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am index cc1b4ef..93ce88e 100644 --- a/openbsc/tests/trau/Makefile.am +++ b/openbsc/tests/trau/Makefile.am @@ -1,17 +1,46 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = trau_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = trau_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -trau_test_SOURCES = trau_test.c -trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBRARY_DL) -ldbi +EXTRA_DIST = \ + trau_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + trau_test \ + $(NULL) + +trau_test_SOURCES = \ + trau_test.c \ + $(NULL) + +trau_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..e7c4cf0 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -1,11 +1,27 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = xid_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = xid_test +EXTRA_DIST = \ + xid_test.ok \ + $(NULL) -xid_test_SOURCES = xid_test.c +noinst_PROGRAMS = \ + xid_test \ + $(NULL) + +xid_test_SOURCES = \ + xid_test.c \ + $(NULL) xid_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ @@ -16,6 +32,8 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm - + -lgtp \ + -lrt \ + -lm \ + $(NULL) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 14 22:52:27 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Wed, 14 Sep 2016 22:52:27 +0000 Subject: [PATCH] openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/839 to look at the new patch set (#2). Build fixes Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 --- M openbsc/src/gprs/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 5 files changed, 11 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/839/2 diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6269722..b51d05a 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -28,10 +28,12 @@ OSMO_LIBS = \ $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOGB_LIBS) \ + $(LIBGTP_LIBS) \ $(NULL) bin_PROGRAMS = \ @@ -95,8 +97,8 @@ $(LIBOSMOABIS_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) if BUILD_IU osmo_sgsn_LDADD += \ @@ -122,6 +124,6 @@ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBCARES_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index 137924d..9231191 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -7,6 +7,8 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBGTP_CFLAGS) \ $(NULL) EXTRA_DIST = \ @@ -35,6 +37,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 7eb14fa..cb35198 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -6,6 +6,7 @@ AM_CFLAGS = \ -Wall \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCRYPTO_CFLAGS) \ $(NULL) diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 1887861..59c1d10 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -7,6 +7,7 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCARES_CFLAGS) \ $(NULL) @@ -64,7 +65,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index e7c4cf0..aaf17ed 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -32,7 +32,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ -lm \ $(NULL) -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 14 23:07:26 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Wed, 14 Sep 2016 23:07:26 +0000 Subject: [PATCH] openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/839 to look at the new patch set (#3). Build fixes Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 --- M openbsc/src/gprs/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 5 files changed, 12 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/839/3 diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6269722..b51d05a 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -28,10 +28,12 @@ OSMO_LIBS = \ $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOGB_LIBS) \ + $(LIBGTP_LIBS) \ $(NULL) bin_PROGRAMS = \ @@ -95,8 +97,8 @@ $(LIBOSMOABIS_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) if BUILD_IU osmo_sgsn_LDADD += \ @@ -122,6 +124,6 @@ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBCARES_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index 137924d..bc3fc0e 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -7,6 +7,9 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBGTP_CFLAGS) \ $(NULL) EXTRA_DIST = \ @@ -35,6 +38,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 7eb14fa..cb35198 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -6,6 +6,7 @@ AM_CFLAGS = \ -Wall \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCRYPTO_CFLAGS) \ $(NULL) diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 1887861..59c1d10 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -7,6 +7,7 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCARES_CFLAGS) \ $(NULL) @@ -64,7 +65,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index e7c4cf0..aaf17ed 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -32,7 +32,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ -lm \ $(NULL) -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 14 23:18:08 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Wed, 14 Sep 2016 23:18:08 +0000 Subject: [PATCH] openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/838 to look at the new patch set (#3). Consistenly format variables in */Makefile.am files Change-Id: Ifa21513c007072314097b7bec188579972dc1694 --- M openbsc/Makefile.am M openbsc/doc/Makefile.am M openbsc/doc/examples/Makefile.am M openbsc/include/Makefile.am M openbsc/include/openbsc/Makefile.am M openbsc/src/Makefile.am M openbsc/src/gprs/Makefile.am M openbsc/src/ipaccess/Makefile.am M openbsc/src/libbsc/Makefile.am M openbsc/src/libcommon/Makefile.am M openbsc/src/libfilter/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/src/libmgcp/Makefile.am M openbsc/src/libmsc/Makefile.am M openbsc/src/libtrau/Makefile.am M openbsc/src/osmo-bsc/Makefile.am M openbsc/src/osmo-bsc_mgcp/Makefile.am M openbsc/src/osmo-bsc_nat/Makefile.am M openbsc/src/osmo-nitb/Makefile.am M openbsc/src/utils/Makefile.am M openbsc/tests/Makefile.am M openbsc/tests/abis/Makefile.am M openbsc/tests/bsc-nat/Makefile.am M openbsc/tests/bsc/Makefile.am M openbsc/tests/channel/Makefile.am M openbsc/tests/db/Makefile.am M openbsc/tests/gbproxy/Makefile.am M openbsc/tests/gsm0408/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mgcp/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/oap/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/smpp/Makefile.am M openbsc/tests/subscr/Makefile.am M openbsc/tests/trau/Makefile.am M openbsc/tests/xid/Makefile.am 37 files changed, 1,478 insertions(+), 461 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/838/3 diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am index 8696eb4..f7eda56 100644 --- a/openbsc/Makefile.am +++ b/openbsc/Makefile.am @@ -1,7 +1,16 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = doc include src tests +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +SUBDIRS = \ + doc \ + include \ + src \ + tests \ + $(NULL) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = openbsc.pc diff --git a/openbsc/doc/Makefile.am b/openbsc/doc/Makefile.am index aee2d7b..5a23107 100644 --- a/openbsc/doc/Makefile.am +++ b/openbsc/doc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = examples +SUBDIRS = \ + examples \ + $(NULL) diff --git a/openbsc/doc/examples/Makefile.am b/openbsc/doc/examples/Makefile.am index 8f14fdc..530c3fa 100644 --- a/openbsc/doc/examples/Makefile.am +++ b/openbsc/doc/examples/Makefile.am @@ -1,4 +1,3 @@ - CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' dist-hook: diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index 4596b6e..3234e62 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,8 @@ -SUBDIRS = openbsc +SUBDIRS = \ + openbsc \ + $(NULL) -noinst_HEADERS = mISDNif.h compat_af_isdn.h +noinst_HEADERS = \ + mISDNif.h \ + compat_af_isdn.h \ + $(NULL) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..cae8ba4 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -1,25 +1,87 @@ -noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ - gsm_subscriber.h gsm_04_11.h debug.h signal.h \ - misdn.h chan_alloc.h paging.h ctrl.h \ - trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ - silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h \ - vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \ - handover_decision.h rrlp.h \ - crc24.h gprs_llc.h gprs_gmm.h \ - gb_proxy.h gprs_sgsn.h sgsn.h \ - auth.h osmo_msc.h bsc_msc.h bsc_nat.h \ - osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \ - osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.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_client.h bsc_msg_filter.h \ - oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ - iu.h +noinst_HEADERS = \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bss.h \ + chan_alloc.h \ + crc24.h \ + ctrl.h \ + db.h \ + debug.h \ + e1_config.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_gsup_client.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp.h \ + gprs_utils.h \ + gsm_04_08.h \ + gsm_04_11.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + gtphub.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ + iu.h \ + meas_feed.h \ + meas_rep.h \ + mgcp.h \ + mgcp_internal.h \ + mgcp_transcode.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + nat_rewrite_trie.h \ + network_listen.h \ + oap.h \ + oap_messages.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_msc_data.h \ + osmux.h \ + paging.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + smpp.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + token_auth.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + $(NULL) -openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h -openbscdir = $(includedir)/openbsc +openbsc_HEADERS = \ + bsc_api.h \ + gsm_04_08.h \ + meas_rep.h \ + $(NULL) + +openbscdir = \ + $(includedir)/openbsc \ + $(NULL) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 4aa880f..272292a 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -1,22 +1,59 @@ -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) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) # Libraries -SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter +SUBDIRS = \ + libcommon \ + libmgcp \ + libbsc \ + libmsc \ + libtrau \ + libfilter \ + $(NULL) # Conditional Libraries if BUILD_IU -SUBDIRS += libiu +SUBDIRS += \ + libiu \ + $(NULL) endif # Programs -SUBDIRS += osmo-nitb osmo-bsc_mgcp utils ipaccess gprs +SUBDIRS += \ + osmo-nitb \ + osmo-bsc_mgcp \ + utils \ + ipaccess \ + gprs \ + $(NULL) # Conditional Programs if BUILD_NAT -SUBDIRS += osmo-bsc_nat +SUBDIRS += \ + osmo-bsc_nat \ + $(NULL) endif + if BUILD_BSC -SUBDIRS += osmo-bsc +SUBDIRS += \ + osmo-bsc \ + $(NULL) endif diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..6269722 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -1,50 +1,127 @@ -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) \ - $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(NULL) -bin_PROGRAMS = osmo-gbproxy +bin_PROGRAMS = \ + osmo-gbproxy \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -bin_PROGRAMS += osmo-sgsn osmo-gtphub +bin_PROGRAMS += \ + osmo-sgsn \ + osmo-gtphub \ + $(NULL) endif endif -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) $(LIBCRYPTO_LIBS) -lrt +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 \ + $(NULL) +osmo_gbproxy_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) -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_utils.c gprs_gsup_client.c \ - sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +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_utils.c \ + gprs_gsup_client.c \ + sgsn_cdr.c \ + sgsn_ares.c \ + oap.c \ + oap_messages.c \ + gprs_llc_xid.c \ + $(NULL) +osmo_sgsn_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif -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 +osmo_gtphub_SOURCES = \ + gtphub_main.c \ + gtphub.c \ + gtphub_sock.c \ + gtphub_ares.c \ + gtphub_vty.c \ + sgsn_ares.c \ + gprs_utils.c \ + $(NULL) +osmo_gtphub_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCARES_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am index 9acc0f7..64bf249 100644 --- a/openbsc/src/ipaccess/Makefile.am +++ b/openbsc/src/ipaccess/Makefile.am @@ -1,26 +1,65 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = abisip-find ipaccess-config ipaccess-proxy +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -abisip_find_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) -abisip_find_SOURCES = abisip-find.c +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -ipaccess_config_SOURCES = ipaccess-config.c ipaccess-firmware.c network_listen.c +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +bin_PROGRAMS = \ + abisip-find \ + ipaccess-config \ + ipaccess-proxy \ + $(NULL) + +abisip_find_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) + +abisip_find_SOURCES = \ + abisip-find.c \ + $(NULL) + +ipaccess_config_SOURCES = \ + ipaccess-config.c \ + ipaccess-firmware.c \ + network_listen.c \ + $(NULL) # FIXME: resolve the bogus dependencies patched around here: ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBCRYPT) $(OSMO_LIBS) + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(OSMO_LIBS) \ + $(NULL) -ipaccess_proxy_SOURCES = ipaccess-proxy.c -ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) +ipaccess_proxy_SOURCES = \ + ipaccess-proxy.c \ + $(NULL) + +ipaccess_proxy_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am index fd8de0e..ad73d1e 100644 --- a/openbsc/src/libbsc/Makefile.am +++ b/openbsc/src/libbsc/Makefile.am @@ -1,28 +1,52 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libbsc.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libbsc_a_SOURCES = abis_nm.c abis_nm_vty.c \ - abis_om2000.c abis_om2000_vty.c \ - abis_rsl.c bsc_rll.c \ - paging.c \ - bts_ericsson_rbs2000.c \ - bts_ipaccess_nanobts.c \ - bts_siemens_bs11.c \ - bts_nokia_site.c \ - bts_unknown.c \ - bts_sysmobts.c \ - chan_alloc.c \ - handover_decision.c handover_logic.c meas_rep.c \ - rest_octets.c system_information.c \ - e1_config.c \ - bsc_api.c bsc_msc.c bsc_vty.c \ - gsm_04_08_utils.c \ - bsc_init.c bts_init.c bsc_rf_ctrl.c \ - arfcn_range_encode.c bsc_ctrl_commands.c \ - bsc_ctrl_lookup.c \ - net_init.c \ - bsc_dyn_ts.c +noinst_LIBRARIES = \ + libbsc.a \ + $(NULL) + +libbsc_a_SOURCES = abis_nm.c \ + abis_nm_vty.c \ + abis_om2000.c \ + abis_om2000_vty.c \ + abis_rsl.c \ + bsc_rll.c \ + paging.c \ + bts_ericsson_rbs2000.c \ + bts_ipaccess_nanobts.c \ + bts_siemens_bs11.c \ + bts_nokia_site.c \ + bts_unknown.c \ + bts_sysmobts.c \ + chan_alloc.c \ + handover_decision.c \ + handover_logic.c \ + meas_rep.c \ + rest_octets.c \ + system_information.c \ + e1_config.c \ + bsc_api.c \ + bsc_msc.c bsc_vty.c \ + gsm_04_08_utils.c \ + bsc_init.c \ + bts_init.c \ + bsc_rf_ctrl.c \ + arfcn_range_encode.c \ + bsc_ctrl_commands.c \ + bsc_ctrl_lookup.c \ + net_init.c \ + bsc_dyn_ts.c \ + $(NULL) diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am index 75f40ee..6cfebc2 100644 --- a/openbsc/src/libcommon/Makefile.am +++ b/openbsc/src/libcommon/Makefile.am @@ -1,9 +1,29 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libcommon.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \ - gsm_data_shared.c socket.c talloc_ctx.c \ - gsm_subscriber_base.c +noinst_LIBRARIES = \ + libcommon.a \ + $(NULL) + +libcommon_a_SOURCES = \ + bsc_version.c \ + common_vty.c \ + debug.c \ + gsm_data.c \ + gsm_data_shared.c \ + socket.c \ + talloc_ctx.c \ + gsm_subscriber_base.c \ + $(NULL) diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am index ed3cd43..6d3db0b 100644 --- a/openbsc/src/libfilter/Makefile.am +++ b/openbsc/src/libfilter/Makefile.am @@ -1,11 +1,26 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libfilter.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libfilter.a \ + $(NULL) libfilter_a_SOURCES = \ bsc_msg_filter.c \ bsc_msg_acc.c \ - bsc_msg_vty.c + bsc_msg_vty.c \ + $(NULL) diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..e5f9e27 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,10 +1,28 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libiu.a +noinst_LIBRARIES = \ + libiu.a \ + $(NULL) -libiu_a_SOURCES = iu.c iu_vty.c +libiu_a_SOURCES = \ + iu.c \ + iu_vty.c \ + $(NULL) diff --git a/openbsc/src/libmgcp/Makefile.am b/openbsc/src/libmgcp/Makefile.am index 4403d60..544a795 100644 --- a/openbsc/src/libmgcp/Makefile.am +++ b/openbsc/src/libmgcp/Makefile.am @@ -1,16 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(COVERAGE_LDFLAGS) $(LIBBCG729_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libmgcp.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_HEADERS = g711common.h +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBBCG729_LIBS) \ + $(NULL) -libmgcp_a_SOURCES = mgcp_protocol.c mgcp_network.c mgcp_vty.c mgcp_osmux.c \ - mgcp_sdp.c +noinst_LIBRARIES = \ + libmgcp.a \ + $(NULL) + +noinst_HEADERS = \ + g711common.h \ + $(NULL) + +libmgcp_a_SOURCES = \ + mgcp_protocol.c \ + mgcp_network.c \ + mgcp_vty.c \ + mgcp_osmux.c \ + mgcp_sdp.c \ + $(NULL) if BUILD_MGCP_TRANSCODING - libmgcp_a_SOURCES += mgcp_transcode.c +libmgcp_a_SOURCES += \ + mgcp_transcode.c \ + $(NULL) endif diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index 5195890..ba44d2e 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -1,27 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_feed.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libmsc.a +noinst_HEADERS = \ + meas_feed.h \ + $(NULL) -libmsc_a_SOURCES = auth.c \ - db.c \ - gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c mncc_builtin.c mncc_sock.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - token_auth.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c ctrl_commands.c meas_feed.c +noinst_LIBRARIES = \ + libmsc.a \ + $(NULL) + +libmsc_a_SOURCES = auth.c \ + db.c \ + gsm_04_08.c \ + gsm_04_11.c \ + gsm_04_11_helper.c \ + gsm_04_80.c \ + gsm_subscriber.c \ + mncc.c \ + mncc_builtin.c \ + mncc_sock.c \ + rrlp.c \ + silent_call.c \ + sms_queue.c \ + token_auth.c \ + ussd.c \ + vty_interface_layer3.c \ + transaction.c \ + osmo_msc.c \ + ctrl_commands.c \ + meas_feed.c \ + $(NULL) if BUILD_SMPP -noinst_HEADERS += smpp_smsc.h -libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c +noinst_HEADERS += \ + smpp_smsc.h \ + $(NULL) + +libmsc_a_SOURCES += \ + smpp_smsc.c \ + smpp_openbsc.c \ + smpp_vty.c \ + smpp_utils.c \ + $(NULL) endif diff --git a/openbsc/src/libtrau/Makefile.am b/openbsc/src/libtrau/Makefile.am index 0fe3a53..46becd6 100644 --- a/openbsc/src/libtrau/Makefile.am +++ b/openbsc/src/libtrau/Makefile.am @@ -1,7 +1,31 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libtrau.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libtrau_a_SOURCES = rtp_proxy.c trau_mux.c trau_upqueue.c +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libtrau.a \ + $(NULL) + +libtrau_a_SOURCES = \ + rtp_proxy.c \ + trau_mux.c \ + trau_upqueue.c \ + $(NULL) diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 4aa1803..b6e7638 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -1,21 +1,56 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc \ + $(NULL) -osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ - osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c +osmo_bsc_SOURCES = \ + osmo_bsc_main.c \ + osmo_bsc_vty.c \ + osmo_bsc_api.c \ + osmo_bsc_grace.c \ + osmo_bsc_msc.c \ + osmo_bsc_sccp.c \ + osmo_bsc_filter.c \ + osmo_bsc_bssap.c \ + osmo_bsc_audio.c \ + osmo_bsc_ctrl.c \ + $(NULL) + # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_mgcp/Makefile.am b/openbsc/src/osmo-bsc_mgcp/Makefile.am index a48f24b..d850be7 100644 --- a/openbsc/src/osmo-bsc_mgcp/Makefile.am +++ b/openbsc/src/osmo-bsc_mgcp/Makefile.am @@ -1,14 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_mgcp +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -osmo_bsc_mgcp_SOURCES = mgcp_main.c +bin_PROGRAMS = \ + osmo-bsc_mgcp \ + $(NULL) + +osmo_bsc_mgcp_SOURCES = \ + mgcp_main.c \ + $(NULL) osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libmgcp/libmgcp.a -lrt \ - $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(LIBBCG729_LIBS) \ - $(LIBRARY_GSM) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_nat/Makefile.am b/openbsc/src/osmo-bsc_nat/Makefile.am index 4a6f74d..2952b4f 100644 --- a/openbsc/src/osmo-bsc_nat/Makefile.am +++ b/openbsc/src/osmo-bsc_nat/Makefile.am @@ -1,19 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBCRYPTO_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_nat +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +bin_PROGRAMS = \ + osmo-bsc_nat \ + $(NULL) -osmo_bsc_nat_SOURCES = bsc_filter.c bsc_mgcp_utils.c bsc_nat.c bsc_nat_utils.c \ - bsc_nat_vty.c bsc_sccp.c bsc_ussd.c bsc_nat_ctrl.c \ - bsc_nat_rewrite.c bsc_nat_rewrite_trie.c bsc_nat_filter.c +osmo_bsc_nat_SOURCES = \ + bsc_filter.c \ + bsc_mgcp_utils.c \ + bsc_nat.c \ + bsc_nat_utils.c \ + bsc_nat_vty.c \ + bsc_sccp.c \ + bsc_ussd.c \ + bsc_nat_ctrl.c \ + bsc_nat_rewrite.c \ + bsc_nat_rewrite_trie.c \ + bsc_nat_filter.c \ + $(NULL) + osmo_bsc_nat_LDADD = \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libfilter/libfilter.a \ - -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-nitb/Makefile.am b/openbsc/src/osmo-nitb/Makefile.am index 3b7cc8d..60514c0 100644 --- a/openbsc/src/osmo-nitb/Makefile.am +++ b/openbsc/src/osmo-nitb/Makefile.am @@ -1,18 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = osmo-nitb +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_nitb_SOURCES = bsc_hack.c +bin_PROGRAMS = \ + osmo-nitb \ + $(NULL) + +osmo_nitb_SOURCES = \ + bsc_hack.c \ + $(NULL) + osmo_nitb_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - -ldbi $(LIBCRYPT) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOABIS_LIBS) $(LIBSMPP34_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..fbeb8ed 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,42 +1,124 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ - $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_db.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = bs11_config isdnsync +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + meas_db.h \ + $(NULL) + +bin_PROGRAMS = \ + bs11_config \ + isdnsync \ + $(NULL) + if HAVE_SQLITE3 -bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db +bin_PROGRAMS += \ + osmo-meas-pcap2db \ + osmo-meas-udp2db \ + $(NULL) endif if HAVE_LIBCDK -bin_PROGRAMS += meas_vis +bin_PROGRAMS += \ + meas_vis \ + $(NULL) endif if BUILD_SMPP -noinst_PROGRAMS = smpp_mirror +noinst_PROGRAMS = \ + smpp_mirror \ + $(NULL) endif -bs11_config_SOURCES = bs11_config.c -bs11_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +bs11_config_SOURCES = \ + bs11_config.c \ + $(NULL) -isdnsync_SOURCES = isdnsync.c +bs11_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) -smpp_mirror_SOURCES = smpp_mirror.c -smpp_mirror_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) +isdnsync_SOURCES = \ + isdnsync.c \ + $(NULL) -meas_vis_SOURCES = meas_vis.c -meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses -meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_SOURCES = \ + smpp_mirror.c \ + $(NULL) -osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c -osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS) -osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(NULL) -osmo_meas_udp2db_SOURCES = meas_udp2db.c meas_db.c -osmo_meas_udp2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(SQLITE3_LIBS) -osmo_meas_udp2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_SOURCES = \ + meas_vis.c \ + $(NULL) + +meas_vis_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lcdk \ + -lncurses \ + $(NULL) + +meas_vis_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_pcap2db_SOURCES = \ + meas_pcap2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_pcap2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + -lpcap \ + $(NULL) + +osmo_meas_pcap2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_udp2db_SOURCES = \ + meas_udp2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_udp2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +osmo_meas_udp2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..b069dff 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,21 +1,46 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid +SUBDIRS = \ + gsm0408 \ + db \ + channel \ + mgcp \ + gprs \ + abis \ + gbproxy \ + trau \ + subscr \ + mm_auth \ + xid \ + $(NULL) if BUILD_NAT -SUBDIRS += bsc-nat bsc-nat-trie +SUBDIRS += \ + bsc-nat \ + bsc-nat-trie \ + $(NULL) endif if BUILD_BSC -SUBDIRS += bsc +SUBDIRS += \ + bsc \ + $(NULL) endif if BUILD_SMPP -SUBDIRS += smpp +SUBDIRS += \ + smpp \ + $(NULL) endif if HAVE_LIBGTP -SUBDIRS += gtphub +SUBDIRS += \ + gtphub \ + $(NULL) + if HAVE_LIBCARES -SUBDIRS += sgsn oap +SUBDIRS += \ + sgsn \ + oap \ + $(NULL) endif endif @@ -38,9 +63,20 @@ echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) vty_test_runner.py ctrl_test_runner.py smpp_test_runner.py +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + vty_test_runner.py \ + ctrl_test_runner.py \ + smpp_test_runner.py \ + $(NULL) + TESTSUITE = $(srcdir)/testsuite -DISTCLEANFILES = atconfig + +DISTCLEANFILES = \ + atconfig \ + $(NULL) if ENABLE_EXT_TESTS python-tests: $(BUILT_SOURCES) diff --git a/openbsc/tests/abis/Makefile.am b/openbsc/tests/abis/Makefile.am index c2e38de..cbc3e07 100644 --- a/openbsc/tests/abis/Makefile.am +++ b/openbsc/tests/abis/Makefile.am @@ -1,17 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = abis_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = abis_test +EXTRA_DIST = \ + abis_test.ok \ + $(NULL) -abis_test_SOURCES = abis_test.c +noinst_PROGRAMS = \ + abis_test \ + $(NULL) + +abis_test_SOURCES = \ + abis_test.c \ + $(NULL) abis_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 26e5500..fa55d27 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -1,26 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_nat_test.ok bsc_data.c barr.cfg barr_dup.cfg prefixes.csv +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_nat_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_nat_test_SOURCES = bsc_nat_test.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c +EXTRA_DIST = \ + bsc_nat_test.ok \ + bsc_data.c \ + barr.cfg \ + barr_dup.cfg \ + prefixes.csv \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_nat_test \ + $(NULL) + +bsc_nat_test_SOURCES = \ + bsc_nat_test.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c + bsc_nat_test_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) \ - $(LIBOSMOCTRL_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am index 8b786ff..ddfa437 100644 --- a/openbsc/tests/bsc/Makefile.am +++ b/openbsc/tests/bsc/Makefile.am @@ -1,18 +1,45 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_test_SOURCES = bsc_test.c \ - $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c -bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) +EXTRA_DIST = \ + bsc_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_test \ + $(NULL) + +bsc_test_SOURCES = \ + bsc_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(NULL) + +bsc_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am index 51b2f83..a94e853 100644 --- a/openbsc/tests/channel/Makefile.am +++ b/openbsc/tests/channel/Makefile.am @@ -1,14 +1,33 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = channel_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = channel_test +EXTRA_DIST = \ + channel_test.ok \ + $(NULL) -channel_test_SOURCES = channel_test.c +noinst_PROGRAMS = \ + channel_test \ + $(NULL) + +channel_test_SOURCES = \ + channel_test.c \ + $(NULL) channel_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ - -ldbi $(LIBOSMOGSM_LIBS) $(LIBCRYPTO_LIBS) + $(LIBOSMOGSM_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am index be3af5f..9ba6b1b 100644 --- a/openbsc/tests/db/Makefile.am +++ b/openbsc/tests/db/Makefile.am @@ -1,17 +1,48 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = db_test.ok db_test.err hlr.sqlite3 +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = db_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -db_test_SOURCES = db_test.c -db_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBCRYPTO_LIBS) -ldbi +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + hlr.sqlite3 \ + $(NULL) + +noinst_PROGRAMS = \ + db_test \ + $(NULL) + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gbproxy/Makefile.am b/openbsc/tests/gbproxy/Makefile.am index 18d77a8..2dd66df 100644 --- a/openbsc/tests/gbproxy/Makefile.am +++ b/openbsc/tests/gbproxy/Makefile.am @@ -1,27 +1,54 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gbproxy_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = gbproxy_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -gbproxy_test_SOURCES = gbproxy_test.c +EXTRA_DIST = \ + gbproxy_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + gbproxy_test \ + $(NULL) + +gbproxy_test_SOURCES = \ + gbproxy_test.c \ + $(NULL) + gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes + -Wl,--wrap=RAND_bytes \ + $(NULL) + gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) -lrt + $(top_builddir)/src/gprs/gb_proxy.o \ + $(top_builddir)/src/gprs/gb_proxy_patch.o \ + $(top_builddir)/src/gprs/gb_proxy_peer.o \ + $(top_builddir)/src/gprs/gb_proxy_tlli.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBRARY_DL) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index 79fb9f1..11fa6b9 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -1,12 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -noinst_PROGRAMS = gsm0408_test +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gsm0408_test.ok +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -gsm0408_test_SOURCES = gsm0408_test.c -gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) -ldbi +noinst_PROGRAMS = \ + gsm0408_test \ + $(NULL) + +EXTRA_DIST = \ + gsm0408_test.ok \ + $(NULL) + +gsm0408_test_SOURCES = \ + gsm0408_test.c \ + $(NULL) + +gsm0408_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..137924d 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,24 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) EXTRA_DIST = \ - gtphub_test.ok + gtphub_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = gtphub_test +noinst_PROGRAMS = \ + gtphub_test \ + $(NULL) endif endif -gtphub_test_SOURCES = gtphub_test.c +gtphub_test_SOURCES = \ + gtphub_test.c \ + $(NULL) + gtphub_test_LDFLAGS = \ -Wl,--wrap=gtphub_resolve_ggsn_addr \ -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write + -Wl,--wrap=gtphub_write \ + $(NULL) gtphub_test_LDADD = \ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt - + -lgtp \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 82d6ac6..4e7a558 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -1,30 +1,73 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_FLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir) \ + $(NULL) -EXTRA_DIST = mgcp_test.ok mgcp_transcoding_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_FLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = mgcp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + mgcp_test.ok \ + mgcp_transcoding_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + mgcp_test \ + $(NULL) if BUILD_MGCP_TRANSCODING -noinst_PROGRAMS += mgcp_transcoding_test +noinst_PROGRAMS += \ + mgcp_transcoding_test \ + $(NULL) endif -mgcp_test_SOURCES = mgcp_test.c +mgcp_test_SOURCES = \ + mgcp_test.c \ + $(NULL) -mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) +mgcp_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + -lrt \ + -lm \ + $(NULL) -mgcp_transcoding_test_SOURCES = mgcp_transcoding_test.c +mgcp_transcoding_test_SOURCES = \ + mgcp_transcoding_test.c \ + $(NULL) mgcp_transcoding_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBBCG729_LIBS) -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) $(LIBRARY_GSM) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + -lm \ + $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..7eb14fa 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -1,21 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -noinst_PROGRAMS = mm_auth_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(NULL) -EXTRA_DIST = mm_auth_test.ok +noinst_PROGRAMS = \ + mm_auth_test \ + $(NULL) -mm_auth_test_SOURCES = mm_auth_test.c +EXTRA_DIST = \ + mm_auth_test.ok \ + $(NULL) + +mm_auth_test_SOURCES = \ + mm_auth_test.c \ + $(NULL) mm_auth_test_LDFLAGS = \ -Wl,--wrap=db_get_authinfo_for_subscr \ -Wl,--wrap=db_get_lastauthtuple_for_subscr \ - -Wl,--wrap=db_sync_lastauthtuple_for_subscr + -Wl,--wrap=db_sync_lastauthtuple_for_subscr \ + $(NULL) -mm_auth_test_LDADD = $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) +mm_auth_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/oap/Makefile.am b/openbsc/tests/oap/Makefile.am index 538e178..06ccf33 100644 --- a/openbsc/tests/oap/Makefile.am +++ b/openbsc/tests/oap/Makefile.am @@ -1,15 +1,30 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = oap_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + oap_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = oap_test +noinst_PROGRAMS = \ + oap_test \ + $(NULL) endif endif -oap_test_SOURCES = oap_test.c +oap_test_SOURCES = \ + oap_test.c \ + $(NULL) oap_test_LDADD = \ $(top_builddir)/src/gprs/oap.o \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..1887861 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,20 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) + if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -EXTRA_DIST = sgsn_test.ok +EXTRA_DIST = \ + sgsn_test.ok \ + $(NULL) -noinst_PROGRAMS = sgsn_test +noinst_PROGRAMS = \ + sgsn_test \ + $(NULL) -sgsn_test_SOURCES = sgsn_test.c +sgsn_test_SOURCES = \ + sgsn_test.c \ + $(NULL) + sgsn_test_LDFLAGS = \ -Wl,--wrap=RAND_bytes \ -Wl,--wrap=sgsn_update_subscriber_data \ -Wl,--wrap=gprs_subscr_request_update_location \ -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gprs_gsup_client_send + -Wl,--wrap=gprs_gsup_client_send \ + $(NULL) sgsn_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_parse.o \ @@ -33,7 +56,7 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -41,12 +64,15 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + -lgtp \ + -lrt \ + $(NULL) + if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) + $(LIBASN1C_LIBS) \ + $(NULL) endif - diff --git a/openbsc/tests/smpp/Makefile.am b/openbsc/tests/smpp/Makefile.am index aab4de9..5082707 100644 --- a/openbsc/tests/smpp/Makefile.am +++ b/openbsc/tests/smpp/Makefile.am @@ -1,13 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/libmsc \ + $(NULL) -EXTRA_DIST = smpp_test.ok smpp_test.err +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = smpp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -smpp_test_SOURCES = smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c +EXTRA_DIST = \ + smpp_test.ok \ + smpp_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + smpp_test \ + $(NULL) + +smpp_test_SOURCES = \ + smpp_test.c \ + $(top_builddir)/src/libmsc/smpp_utils.c \ + $(NULL) + smpp_test_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/subscr/Makefile.am b/openbsc/tests/subscr/Makefile.am index 4f96dc9..72f97e6 100644 --- a/openbsc/tests/subscr/Makefile.am +++ b/openbsc/tests/subscr/Makefile.am @@ -1,18 +1,42 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = subscr_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = subscr_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -subscr_test_SOURCES = subscr_test.c -subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -# -ldbi +EXTRA_DIST = \ + subscr_test.ok \ + $(NULL) +noinst_PROGRAMS = \ + subscr_test \ + $(NULL) + +subscr_test_SOURCES = \ + subscr_test.c \ + $(NULL) + +subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(NULL) diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am index cc1b4ef..93ce88e 100644 --- a/openbsc/tests/trau/Makefile.am +++ b/openbsc/tests/trau/Makefile.am @@ -1,17 +1,46 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = trau_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = trau_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -trau_test_SOURCES = trau_test.c -trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBRARY_DL) -ldbi +EXTRA_DIST = \ + trau_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + trau_test \ + $(NULL) + +trau_test_SOURCES = \ + trau_test.c \ + $(NULL) + +trau_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..e7c4cf0 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -1,11 +1,27 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = xid_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = xid_test +EXTRA_DIST = \ + xid_test.ok \ + $(NULL) -xid_test_SOURCES = xid_test.c +noinst_PROGRAMS = \ + xid_test \ + $(NULL) + +xid_test_SOURCES = \ + xid_test.c \ + $(NULL) xid_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ @@ -16,6 +32,8 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm - + -lgtp \ + -lrt \ + -lm \ + $(NULL) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 06:36:40 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 06:36:40 +0000 Subject: osmo-pcu[master]: EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/826/1/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 513: OSMO_ASSERT(chunks[1].offset == 1); > could these additional asserts already be in the previous patch (with diffe No. Due to current bug we see only 1 chunk. i.e index 0. with current fix we see index 1 i.e 2 chunks. -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 06:40:11 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 06:40:11 +0000 Subject: osmo-pcu[master]: EGPRS: Adds support of row 4 of Table 10.4.14a.1 of 44.060 In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/826/1/src/decoding.cpp File src/decoding.cpp: Line 77: chunks[num_chunks].is_complete = true; > Are you sure is_complete shall always be true here? spec says as below==> /* TS 44.060, table 10.4.14a.1, row 4 */ 1st LI: value=0 1 The previous RLC data block contains a Upper Layer PDU, or a part of it, that fills precisely the previous data block and for which there is no length indicator in that RLC data block. The current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or continues in the next RLC data blcok. -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:12:13 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:12:13 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#9). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060 version 7.27.0 Release 7. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 289 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/9 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..592ad63 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,34 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 1; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we expect 2 chunks here + * index 0 as complete and index 1 as incomplete + * due to current bug we see only 1 chunk + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(!chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..9f040ff 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:12:13 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:12:13 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/826 to look at the new patch set (#2). EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1 of Spec 44.060 version 7.27.0 Release 7. Says "The previous RLC data block contains a Upper Layer PDU, or a part of it, that fills precisely the previous data block and for which there is no length indicator in that RLC data block. The current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or continues in the next RLC data block." So when we receive block with 1st LI: value=0 and Value of E bit in the same octet as 1, we expect 2 chunks with 1st chunk as length as 0 and complete and 2nd chunk as length non zero. But with this bug we see only 1 chunk causing incorrect assembling This issue has been fixed in this patch. Related: OS#1811 Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b --- M src/decoding.cpp M src/tbf_ul.cpp M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 5 files changed, 24 insertions(+), 28 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/26/826/2 diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..515a75c 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -73,8 +73,8 @@ chunks[num_chunks].is_complete = true; } else if (li->li == 0 && num_chunks == 0 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 4 */ - chunks[num_chunks].length = LENGTH_TO_END; - chunks[num_chunks].is_complete = is_last_block; + chunks[num_chunks].length = 0; + chunks[num_chunks].is_complete = true; } else if (li->li == 127 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 3 & 5 */ /* only filling bytes left */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 7e0732c..f67ffd7 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -67,14 +67,18 @@ for (i = 0; i < num_frames; i++) { frame = frames + i; - bts->rlc_ul_payload_bytes(frame->length); + if (frame->length) { + bts->rlc_ul_payload_bytes(frame->length); - LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d starts at offset %d, " - "length=%d, is_complete=%d\n", - i + 1, frame->offset, frame->length, frame->is_complete); + LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d " + "starts at offset %d, " + "length=%d, is_complete=%d\n", + i + 1, frame->offset, frame->length, + frame->is_complete); - m_llc.append_frame(data + frame->offset, frame->length); - m_llc.consume(frame->length); + m_llc.append_frame(data + frame->offset, frame->length); + m_llc.consume(frame->length); + } if (frame->is_complete) { /* send frame to SGSN */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 592ad63..3537aa7 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,13 +496,6 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); - /* - * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 - * row 4 of Table 10.4.14a.1 - * should expect 2 chunks. but currently it fails - * due to bug. The assert will be fixed along with actual - * fix - */ rdbi.e = 0; rdbi.ti = 0; rdbi.cv = 1; @@ -512,17 +505,14 @@ num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, chunks, ARRAY_SIZE(chunks), &tlli); - /* - * TODO: we expect 2 chunks here - * index 0 as complete and index 1 as incomplete - * due to current bug we see only 1 chunk - * assert for index 1 will be added in subsequent - * patch - */ - OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(num_chunks == 2); OSMO_ASSERT(chunks[0].offset == 1); - OSMO_ASSERT(chunks[0].length == 43); - OSMO_ASSERT(!chunks[0].is_complete); + OSMO_ASSERT(chunks[0].length == 0); + OSMO_ASSERT(chunks[0].is_complete); + + OSMO_ASSERT(chunks[1].offset == 1); + OSMO_ASSERT(chunks[1].length == 43); + OSMO_ASSERT(!chunks[1].is_complete); printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 9f040ff..42542d1 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1980,8 +1980,7 @@ data_msg[5] = 0x0; pdch->rcv_block(data_msg, 49, *fn, &meas); - /* TODO: should expect m_index as 43 */ - OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + OSMO_ASSERT(ul_tbf->m_llc.m_index == 43); return ul_tbf; } diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 06b63eb..90f04be 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6489,7 +6489,10 @@ - Raising V(R) to 2 - Taking block 1 out, raising V(Q) to 2 - Assembling frames: (len=44) --- Frame 1 starts at offset 1, length=43, is_complete=0 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) complete UL frame len=44 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) len=44 +No bctx +-- Frame 2 starts at offset 1, length=43, is_complete=0 - No gaps in received block, last block: BSN=1 CV=7 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:13:45 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:13:45 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 9: (1 comment) https://gerrit.osmocom.org/#/c/825/1/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2011: ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, > if tbf_li_decoding() is used only by this test, IMHO it should Done -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:43:34 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:43:34 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 9: (1 comment) https://gerrit.osmocom.org/#/c/825/9/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2701: test_tbf_li_decoding(); Re trigger the build. -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:44:11 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:44:11 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#10). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060 version 7.27.0 Release 7. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 289 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/10 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..592ad63 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,34 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 1; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we expect 2 chunks here + * index 0 as complete and index 1 as incomplete + * due to current bug we see only 1 chunk + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(!chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..2c49074 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 10 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:45:58 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:45:58 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 10: (1 comment) https://gerrit.osmocom.org/#/c/825/10/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2701: test_tbf_li_decoding(); now fixing it -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 10 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 07:46:20 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 07:46:20 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#11). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060 version 7.27.0 Release 7. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 289 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/11 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..592ad63 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,34 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 1; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we expect 2 chunks here + * index 0 as complete and index 1 as incomplete + * due to current bug we see only 1 chunk + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(!chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..9f040ff 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.Exist_EGPRS_multislot_class = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Multislot_capability.EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 11 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 10:53:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 10:53:22 +0000 Subject: osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: Patch Set 2: (2 comments) https://gerrit.osmocom.org/#/c/826/2/src/decoding.cpp File src/decoding.cpp: Line 77: chunks[num_chunks].is_complete = true; I know what the spec says, which I quoted in my question. Quoting the same spec again doesn't answer my question. To approve of the patch, I need to understand what it means in terms of this code. My understanding is lacking here: does is_complete refer to the PDU? If it does, then is_complete == true would mean that the PDU always ends, but the spec says the PDU may continue in the next data block. So I guess is_complete refers only to one part of a PDU. Since you probably have a better understanding of what is happening here, can you explain in detail why is_complete must always be true here? And once you've explained it and you're sure it is correct, you should combine the row 4 if {} with above row 2a if {}, as I posted above. https://gerrit.osmocom.org/#/c/826/1/tests/edge/EdgeTest.cpp File tests/edge/EdgeTest.cpp: Line 513: OSMO_ASSERT(chunks[1].offset == 1); > No. Due to current bug we see only 1 chunk. i.e index 0. with current fix w ah of course, now I see the num_chunks == 2 assertion above. -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 10:59:59 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 10:59:59 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 11: (2 comments) https://gerrit.osmocom.org/#/c/825/10/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2701: test_tbf_li_decoding(); > now fixing it that's nice, but no reason to post a comment. https://gerrit.osmocom.org/#/c/825/11/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 1917: Exist_Multislot_capability = 1; presreq is great; You should also have a shortcut for MS_RA_capability_value[0].u.Content and/or ..Multislot_capability (after which the pmsradiocap shortcut can probably be dropped again) -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 11 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 11:02:17 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 11:02:17 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 11: (1 comment) https://gerrit.osmocom.org/#/c/825/10/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2701: test_tbf_li_decoding(); > that's nice, but no reason to post a comment. It was intentionally done to rebuild. as it was failing earlier with below log. I am not sure about it Caused by: hudson.plugins.git.GitException: Command "git -c core.askpass=true fetch --tags --progress ssh://jenkins at gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/9" returned status code 128: stdout: stderr: socket: Protocol not supported ssh: connect to host gerrit.osmocom.org port 29418: Protocol not supported fatal: Could not read from remote repository. Please make sure you have the correct access rights -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 11 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 11:07:42 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 11:07:42 +0000 Subject: osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/826/2/src/decoding.cpp File src/decoding.cpp: Line 77: chunks[num_chunks].is_complete = true; > I know what the spec says, which I quoted in my question. Quoting the same Hi neels, What i meant was, When we receive this condition. That means there was a pdu which ended in last block but there was no LI to indicate it. so the old PDU is still pending in the buffer. when this block received, we have to conclude the same and send the old PDU towards SGSN. and New LLC PDU starts with this block and it may end or continue in next block. So we have to set 1 chunk(index 0) with complete as true and length as 0. and next chunk details will be concluded below. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 11:32:26 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 11:32:26 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/826 to look at the new patch set (#3). EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1 of Spec 44.060 version 7.27.0 Release 7. Says "The previous RLC data block contains a Upper Layer PDU, or a part of it, that fills precisely the previous data block and for which there is no length indicator in that RLC data block. The current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or continues in the next RLC data block." So when we receive block with 1st LI: value=0 and Value of E bit in the same octet as 1, we expect 2 chunks with 1st chunk as length as 0 and complete and 2nd chunk as length non zero. But with this bug we see only 1 chunk causing incorrect assembling This issue has been fixed in this patch. Related: OS#1811 Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b --- M src/decoding.cpp M src/tbf_ul.cpp M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 5 files changed, 24 insertions(+), 31 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/26/826/3 diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..3f5c4d2 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -67,14 +67,11 @@ "but no more chunks possible\n"); return -ENOSPC; } - if (li->li == 0 && num_chunks == 0 && li->e == 0) { + if (li->li == 0 && num_chunks == 0) { /* TS 44.060, table 10.4.14a.1, row 2a */ + /* TS 44.060, table 10.4.14a.1, row 4 */ chunks[num_chunks].length = 0; chunks[num_chunks].is_complete = true; - } else if (li->li == 0 && num_chunks == 0 && li->e == 1) { - /* TS 44.060, table 10.4.14a.1, row 4 */ - chunks[num_chunks].length = LENGTH_TO_END; - chunks[num_chunks].is_complete = is_last_block; } else if (li->li == 127 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 3 & 5 */ /* only filling bytes left */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 7e0732c..f67ffd7 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -67,14 +67,18 @@ for (i = 0; i < num_frames; i++) { frame = frames + i; - bts->rlc_ul_payload_bytes(frame->length); + if (frame->length) { + bts->rlc_ul_payload_bytes(frame->length); - LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d starts at offset %d, " - "length=%d, is_complete=%d\n", - i + 1, frame->offset, frame->length, frame->is_complete); + LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d " + "starts at offset %d, " + "length=%d, is_complete=%d\n", + i + 1, frame->offset, frame->length, + frame->is_complete); - m_llc.append_frame(data + frame->offset, frame->length); - m_llc.consume(frame->length); + m_llc.append_frame(data + frame->offset, frame->length); + m_llc.consume(frame->length); + } if (frame->is_complete) { /* send frame to SGSN */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 592ad63..3537aa7 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,13 +496,6 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); - /* - * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 - * row 4 of Table 10.4.14a.1 - * should expect 2 chunks. but currently it fails - * due to bug. The assert will be fixed along with actual - * fix - */ rdbi.e = 0; rdbi.ti = 0; rdbi.cv = 1; @@ -512,17 +505,14 @@ num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, chunks, ARRAY_SIZE(chunks), &tlli); - /* - * TODO: we expect 2 chunks here - * index 0 as complete and index 1 as incomplete - * due to current bug we see only 1 chunk - * assert for index 1 will be added in subsequent - * patch - */ - OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(num_chunks == 2); OSMO_ASSERT(chunks[0].offset == 1); - OSMO_ASSERT(chunks[0].length == 43); - OSMO_ASSERT(!chunks[0].is_complete); + OSMO_ASSERT(chunks[0].length == 0); + OSMO_ASSERT(chunks[0].is_complete); + + OSMO_ASSERT(chunks[1].offset == 1); + OSMO_ASSERT(chunks[1].length == 43); + OSMO_ASSERT(!chunks[1].is_complete); printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 9f040ff..42542d1 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1980,8 +1980,7 @@ data_msg[5] = 0x0; pdch->rcv_block(data_msg, 49, *fn, &meas); - /* TODO: should expect m_index as 43 */ - OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + OSMO_ASSERT(ul_tbf->m_llc.m_index == 43); return ul_tbf; } diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 06b63eb..90f04be 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6489,7 +6489,10 @@ - Raising V(R) to 2 - Taking block 1 out, raising V(Q) to 2 - Assembling frames: (len=44) --- Frame 1 starts at offset 1, length=43, is_complete=0 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) complete UL frame len=44 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) len=44 +No bctx +-- Frame 2 starts at offset 1, length=43, is_complete=0 - No gaps in received block, last block: BSN=1 CV=7 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 11:55:16 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 11:55:16 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/825 to look at the new patch set (#12). EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060 version 7.27.0 Release 7. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 289 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/25/825/12 diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..592ad63 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,34 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 1; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we expect 2 chunks here + * index 0 as complete and index 1 as incomplete + * due to current bug we see only 1 chunk + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(!chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..36aadc5 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + Multislot_capability_t *pmultislotcap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmultislotcap = &pmsradiocap->MS_RA_capability_value[0]. + u.Content.Multislot_capability; + + pmultislotcap->Exist_GPRS_multislot_class = 1; + pmultislotcap->GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmultislotcap->Exist_EGPRS_multislot_class = 1; + pmultislotcap->EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 12 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 11:57:24 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 11:57:24 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 8: Hi All, Let me know if any comments for this patch set. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:09:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:09:31 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: Patch Set 12: Code-Review+2 (1 comment) thanks for the explanation! https://gerrit.osmocom.org/#/c/825/12/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 1921: (blank line could be dropped) -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 12 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:10:27 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 12:10:27 +0000 Subject: [MERGED] osmo-pcu[master]: EGPRS: add test case to show LI decoding bug In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: EGPRS: add test case to show LI decoding bug ...................................................................... EGPRS: add test case to show LI decoding bug This patch adds a test case test_tbf_li_decoding which expects a current bug with LI decoding for row 4 of Table 10.4.14a.1 in 44.060 version 7.27.0 Release 7. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1811 Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 --- M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 289 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9081d4d..592ad63 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,6 +496,34 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); + /* + * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 + * row 4 of Table 10.4.14a.1 + * should expect 2 chunks. but currently it fails + * due to bug. The assert will be fixed along with actual + * fix + */ + rdbi.e = 0; + rdbi.ti = 0; + rdbi.cv = 1; + tlli = 0; + offs = 0; + data[offs++] = 1; + num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, + chunks, ARRAY_SIZE(chunks), &tlli); + + /* + * TODO: we expect 2 chunks here + * index 0 as complete and index 1 as incomplete + * due to current bug we see only 1 chunk + * assert for index 1 will be added in subsequent + * patch + */ + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(chunks[0].offset == 1); + OSMO_ASSERT(chunks[0].length == 43); + OSMO_ASSERT(!chunks[0].is_complete); + printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index cdf8ff4..36aadc5 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1870,6 +1870,157 @@ printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0, i = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + struct pcu_l1_meas meas; + struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; + GprsCodingScheme cs; + Packet_Resource_Request_t *presreq = NULL; + MS_Radio_Access_capability_t *pmsradiocap = NULL; + Multislot_capability_t *pmultislotcap = NULL; + + meas.set_rssi(31); + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, fn); + + /* + * simulate RACH, this sends an Immediate + * Assignment Uplink on the AGCH + */ + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + presreq = &ulreq.u.Packet_Resource_Request; + presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + presreq->ID.UnionType = 1; /* != 0 */ + presreq->ID.u.TLLI = tlli; + presreq->Exist_MS_Radio_Access_capability = 1; + pmsradiocap = &presreq->MS_Radio_Access_capability; + pmsradiocap->Count_MS_RA_capability_value = 1; + pmsradiocap->MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + pmultislotcap = &pmsradiocap->MS_RA_capability_value[0]. + u.Content.Multislot_capability; + + pmultislotcap->Exist_GPRS_multislot_class = 1; + pmultislotcap->GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + pmultislotcap->Exist_EGPRS_multislot_class = 1; + pmultislotcap->EGPRS_multislot_class = ms_class; + } + + send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* send packet uplink assignment */ + *fn = sba_fn; + request_dl_rlc_block(ul_tbf, fn); + + /* send real acknowledgement */ + send_control_ack(ul_tbf); + + check_tbf(ul_tbf); + + uint8_t data_msg[49] = {0}; + + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + + ms = the_bts->ms_by_tlli(tlli); + OSMO_ASSERT(ms != NULL); + OSMO_ASSERT(ms->ta() == qta/4); + OSMO_ASSERT(ms->ul_tbf() == ul_tbf); + + cs = GprsCodingScheme::MCS4; + egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; + egprs3->si = 0; + egprs3->r = 1; + egprs3->cv = 7; + egprs3->tfi_hi = tfi & 0x03; + egprs3->tfi_lo = (tfi & 0x1c) >> 2; + egprs3->bsn1_hi = 0; + egprs3->bsn1_lo = 0; + egprs3->cps_hi = 1; + data_msg[3] = 0xff; + egprs3->pi = 0; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + egprs3->bsn1_hi = 1; + egprs3->bsn1_lo = 0; + data_msg[3] = 0x7f; + egprs3->cps_lo = 1; + egprs3->rsb = 0; + egprs3->spb = 0; + egprs3->pi = 0; + data_msg[4] = 0x2; + data_msg[5] = 0x0; + pdch->rcv_block(data_msg, 49, *fn, &meas); + + /* TODO: should expect m_index as 43 */ + OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + + return ul_tbf; +} + +static void test_tbf_li_decoding(void) +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = tbf_li_decoding(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, + "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2547,6 +2698,7 @@ test_tbf_egprs_spb_dl(); test_tbf_puan_urbb_len(); test_tbf_update_ws(); + test_tbf_li_decoding(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a83353c..06b63eb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6410,3 +6410,110 @@ Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 220 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=33 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 0, length=44, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=7 +Got RLC block, coding scheme: MCS-4, length: 49 (49)) + UL data: 1d 08 40 41 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 +UL DATA TFI=0 received (V(Q)=1 .. V(R)=1) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got MCS-4 RLC data block: CV=7, BSN=1, SPB=0, PI=0, E=0, TI=0, bitoffs=33 +- BSN 1 storing in window (1..64) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=44, data=01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 2 +- Taking block 1 out, raising V(Q) to 2 +- Assembling frames: (len=44) +-- Frame 1 starts at offset 1, length=43, is_complete=0 +- No gaps in received block, last block: BSN=1 CV=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 13ad362..eb870ea 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -64,3 +64,5 @@ === end test_tbf_puan_urbb_len === === start test_tbf_update_ws === === end test_tbf_update_ws === +=== start test_tbf_li_decoding === +=== end test_tbf_li_decoding === -- To view, visit https://gerrit.osmocom.org/825 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ida410dab1aa4b0cf3e15b2090586377eb19b2469 Gerrit-PatchSet: 12 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:10:40 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:10:40 +0000 Subject: osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:10:46 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 12:10:46 +0000 Subject: [MERGED] osmo-pcu[master]: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 ve... In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 version 7.27.0 Release 7 ...................................................................... EGPRS: Fix issue with row 4 of Table 10.4.14a.1 of 44.060 version 7.27.0 Release 7 row 4 of Table 10.4.14a.1 of Spec 44.060 version 7.27.0 Release 7. Says "The previous RLC data block contains a Upper Layer PDU, or a part of it, that fills precisely the previous data block and for which there is no length indicator in that RLC data block. The current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or continues in the next RLC data block." So when we receive block with 1st LI: value=0 and Value of E bit in the same octet as 1, we expect 2 chunks with 1st chunk as length as 0 and complete and 2nd chunk as length non zero. But with this bug we see only 1 chunk causing incorrect assembling This issue has been fixed in this patch. Related: OS#1811 Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b --- M src/decoding.cpp M src/tbf_ul.cpp M tests/edge/EdgeTest.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 5 files changed, 24 insertions(+), 31 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c00ff7..3f5c4d2 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -67,14 +67,11 @@ "but no more chunks possible\n"); return -ENOSPC; } - if (li->li == 0 && num_chunks == 0 && li->e == 0) { + if (li->li == 0 && num_chunks == 0) { /* TS 44.060, table 10.4.14a.1, row 2a */ + /* TS 44.060, table 10.4.14a.1, row 4 */ chunks[num_chunks].length = 0; chunks[num_chunks].is_complete = true; - } else if (li->li == 0 && num_chunks == 0 && li->e == 1) { - /* TS 44.060, table 10.4.14a.1, row 4 */ - chunks[num_chunks].length = LENGTH_TO_END; - chunks[num_chunks].is_complete = is_last_block; } else if (li->li == 127 && li->e == 1) { /* TS 44.060, table 10.4.14a.1, row 3 & 5 */ /* only filling bytes left */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 7e0732c..f67ffd7 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -67,14 +67,18 @@ for (i = 0; i < num_frames; i++) { frame = frames + i; - bts->rlc_ul_payload_bytes(frame->length); + if (frame->length) { + bts->rlc_ul_payload_bytes(frame->length); - LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d starts at offset %d, " - "length=%d, is_complete=%d\n", - i + 1, frame->offset, frame->length, frame->is_complete); + LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d " + "starts at offset %d, " + "length=%d, is_complete=%d\n", + i + 1, frame->offset, frame->length, + frame->is_complete); - m_llc.append_frame(data + frame->offset, frame->length); - m_llc.consume(frame->length); + m_llc.append_frame(data + frame->offset, frame->length); + m_llc.consume(frame->length); + } if (frame->is_complete) { /* send frame to SGSN */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 592ad63..3537aa7 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -496,13 +496,6 @@ OSMO_ASSERT(chunks[2].length == 1); OSMO_ASSERT(!chunks[2].is_complete); - /* - * TODO: simulate 3GPP TS 44.060 version 7.27.0 Release 7 - * row 4 of Table 10.4.14a.1 - * should expect 2 chunks. but currently it fails - * due to bug. The assert will be fixed along with actual - * fix - */ rdbi.e = 0; rdbi.ti = 0; rdbi.cv = 1; @@ -512,17 +505,14 @@ num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data, chunks, ARRAY_SIZE(chunks), &tlli); - /* - * TODO: we expect 2 chunks here - * index 0 as complete and index 1 as incomplete - * due to current bug we see only 1 chunk - * assert for index 1 will be added in subsequent - * patch - */ - OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(num_chunks == 2); OSMO_ASSERT(chunks[0].offset == 1); - OSMO_ASSERT(chunks[0].length == 43); - OSMO_ASSERT(!chunks[0].is_complete); + OSMO_ASSERT(chunks[0].length == 0); + OSMO_ASSERT(chunks[0].is_complete); + + OSMO_ASSERT(chunks[1].offset == 1); + OSMO_ASSERT(chunks[1].length == 43); + OSMO_ASSERT(!chunks[1].is_complete); printf("=== end %s ===\n", __func__); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 36aadc5..4e37aa8 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1980,8 +1980,7 @@ data_msg[5] = 0x0; pdch->rcv_block(data_msg, 49, *fn, &meas); - /* TODO: should expect m_index as 43 */ - OSMO_ASSERT(ul_tbf->m_llc.m_index == 87); + OSMO_ASSERT(ul_tbf->m_llc.m_index == 43); return ul_tbf; } diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 06b63eb..90f04be 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6489,7 +6489,10 @@ - Raising V(R) to 2 - Taking block 1 out, raising V(Q) to 2 - Assembling frames: (len=44) --- Frame 1 starts at offset 1, length=43, is_complete=0 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) complete UL frame len=44 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) len=44 +No bctx +-- Frame 2 starts at offset 1, length=43, is_complete=0 - No gaps in received block, last block: BSN=1 CV=7 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 -- To view, visit https://gerrit.osmocom.org/826 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2cd0fca3ed28a553ede3f4b8a7d3267284dd2c9b Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:28:44 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:28:44 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (21 comments) some comments if you'd like to be perfectionist about it ;) ...not that there aren't important tasks waiting :P https://gerrit.osmocom.org/#/c/838/3/openbsc/src/gprs/Makefile.am File openbsc/src/gprs/Makefile.am: Line 40: drop this blank line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/ipaccess/Makefile.am File openbsc/src/ipaccess/Makefile.am: Line 49: ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ start with '= \' and libbsc.a in next line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/libbsc/Makefile.am File openbsc/src/libbsc/Makefile.am: Line 20: libbsc_a_SOURCES = abis_nm.c \ abis_nm.c on next line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/libmgcp/Makefile.am File openbsc/src/libmgcp/Makefile.am: Line 39: drop this blank line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/libmsc/Makefile.am File openbsc/src/libmsc/Makefile.am: Line 25: libmsc_a_SOURCES = auth.c \ auth.c in next line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/osmo-bsc/Makefile.am File openbsc/src/osmo-bsc/Makefile.am: Line 27: drop one of the two blank lines https://gerrit.osmocom.org/#/c/838/3/openbsc/src/osmo-bsc_mgcp/Makefile.am File openbsc/src/osmo-bsc_mgcp/Makefile.am: Line 25: osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ libcommon.a on next line? https://gerrit.osmocom.org/#/c/838/3/openbsc/src/osmo-bsc_nat/Makefile.am File openbsc/src/osmo-bsc_nat/Makefile.am: Line 28: double blank line, drop one https://gerrit.osmocom.org/#/c/838/3/openbsc/src/utils/Makefile.am File openbsc/src/utils/Makefile.am: Line 30: drop this blank line? https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/Makefile.am File openbsc/tests/Makefile.am: Line 14: drop this blank line? Line 21: and this Line 27: and this Line 33: and this Line 38: and this Line 47: double blank line https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/channel/Makefile.am File openbsc/tests/channel/Makefile.am: Line 24: $(NULL) I like it when things related to one binary don't have blank lines in-between, but it seems the other places all have a blank line now. https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/db/Makefile.am File openbsc/tests/db/Makefile.am: Line 34: db_test_LDADD = \ tab before '\' should be space https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/mgcp/Makefile.am File openbsc/tests/mgcp/Makefile.am: Line 30: drop this blank line? https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/sgsn/Makefile.am File openbsc/tests/sgsn/Makefile.am: Line 13: drop this blank line? Line 70: drop this blank line? https://gerrit.osmocom.org/#/c/838/3/openbsc/tests/subscr/Makefile.am File openbsc/tests/subscr/Makefile.am: Line 32: subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ double space before '='. libbsc on next line? -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:29:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:29:58 +0000 Subject: openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:33:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:33:10 +0000 Subject: openbsc[master]: DTX: store time instead of fn In-Reply-To: References: Message-ID: Patch Set 1: looks like some things are missing in this patch, probably those msec related things in #845. -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:36:54 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 15 Sep 2016 12:36:54 +0000 Subject: openbsc[master]: DTX: store time instead of fn In-Reply-To: References: Message-ID: Patch Set 1: #845 (osmo-bts) depends on this one. -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:38:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:38:51 +0000 Subject: osmo-bts[master]: lc15, sysmo: fix last SID store/repeat In-Reply-To: References: Message-ID: Patch Set 2: It sounds like this combines two things that should be separate. Firstly, you say something was forgotten when save_last_sid() was added. Then at the same time you change how it works and add msec stuff? -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:41:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 12:41:55 +0000 Subject: openbsc[master]: DTX: store time instead of fn In-Reply-To: References: Message-ID: Patch Set 1: ah I understand now. The commit log says "store", but this patch doesn't store anything, that's why I wondered. Let's tweak the commit log to "modify struct to store..." and add a hint that this is needed for a fix in osmo-bts. -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 12:58:32 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Thu, 15 Sep 2016 12:58:32 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 22: > > ok, good to see that it's on purpose. > > Maybe a comment would be good for the next guy wondering? > > Done. I have addressed all the comments raised. please let me know the status. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 22 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 13:08:44 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 13:08:44 +0000 Subject: osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 13:09:12 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 13:09:12 +0000 Subject: [MERGED] osmo-pcu[master]: tbf_dl: factor out EGPRS DL window size calculation In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: tbf_dl: factor out EGPRS DL window size calculation ...................................................................... tbf_dl: factor out EGPRS DL window size calculation A subsequent patch needs to call this from gprs_rlcmac_tbf::update(), so to avoid code dup, put the calculation in a separate function. Related: OS#1808 Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 --- M src/tbf.cpp M src/tbf.h M src/tbf_dl.cpp 3 files changed, 24 insertions(+), 14 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/tbf.cpp b/src/tbf.cpp index 7a15547..cbc0710 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -781,20 +781,8 @@ return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } + if (tbf->is_egprs_enabled()) + tbf->egprs_calc_window_size(); llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/src/tbf.h b/src/tbf.h index 2a1bfe8..3a6f42d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -372,6 +372,8 @@ int release(); int abort(); + void egprs_calc_window_size(); + /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 489020b..457f2c9 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -1322,3 +1322,23 @@ /* Non SPB cases 0 is reurned */ return EGPRS_RLCMAC_DL_NO_RETX; } + +void gprs_rlcmac_dl_tbf::egprs_calc_window_size() +{ + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + unsigned int num_pdch = pcu_bitcount(dl_slots()); + unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch; + + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + name(), ws); + + m_window.set_ws(ws); +} -- To view, visit https://gerrit.osmocom.org/832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7c7777d43f843bbd3421503fc2a8600f148ca035 Gerrit-PatchSet: 7 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 13:09:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 13:09:32 +0000 Subject: osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: Patch Set 9: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 13:10:15 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 15 Sep 2016 13:10:15 +0000 Subject: [MERGED] osmo-pcu[master]: Fix EGPRS DL window calculation during tbf update In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: Fix EGPRS DL window calculation during tbf update ...................................................................... Fix EGPRS DL window calculation during tbf update Earlier there was no handling for recalculation of DL window size during tbf update. Which has been fixed in this patch. Related: OS#1808 Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 --- M src/tbf.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 3 files changed, 10 insertions(+), 6 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/tbf.cpp b/src/tbf.cpp index cbc0710..97696cb 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -376,6 +376,12 @@ return -rc; } + if (is_egprs_enabled()) { + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + if (dl_tbf) + dl_tbf->egprs_calc_window_size(); + } + return 0; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 4e37aa8..3e17d8f 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1816,17 +1816,14 @@ dl_tbf->update(); - /* - * TODO: Should not expect window size as 192. - * should be fixed in subsequent patch - */ + /* window size should be 384 */ OSMO_ASSERT(dl_tbf != NULL); fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", dl_tbf->dl_slots(), pcu_bitcount(dl_tbf->dl_slots()), dl_tbf->window()->ws()); OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); - OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 1 * 64); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 90f04be..0c9c877 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6400,7 +6400,8 @@ PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. - Assigning DL TS 5 PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. -DL TBF slots: 0x3c, N: 4, WS: 192 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -- To view, visit https://gerrit.osmocom.org/798 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I41aa807068520460fd665a55e3529e60f6bbb630 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 15 13:26:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 13:26:01 +0000 Subject: [ABANDON] openbsc[master]: Build fixes and cleanups In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: Build fixes and cleanups ...................................................................... Abandoned superseded by #838 and #839 -- To view, visit https://gerrit.osmocom.org/824 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I9bd4f7a0b0bce0184f093ac61099c6681a458f65 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 14:03:39 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Thu, 15 Sep 2016 14:03:39 +0000 Subject: [PATCH] openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/838 to look at the new patch set (#4). Consistenly format variables in */Makefile.am files Change-Id: Ifa21513c007072314097b7bec188579972dc1694 --- M openbsc/Makefile.am M openbsc/doc/Makefile.am M openbsc/doc/examples/Makefile.am M openbsc/include/Makefile.am M openbsc/include/openbsc/Makefile.am M openbsc/src/Makefile.am M openbsc/src/gprs/Makefile.am M openbsc/src/ipaccess/Makefile.am M openbsc/src/libbsc/Makefile.am M openbsc/src/libcommon/Makefile.am M openbsc/src/libfilter/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/src/libmgcp/Makefile.am M openbsc/src/libmsc/Makefile.am M openbsc/src/libtrau/Makefile.am M openbsc/src/osmo-bsc/Makefile.am M openbsc/src/osmo-bsc_mgcp/Makefile.am M openbsc/src/osmo-bsc_nat/Makefile.am M openbsc/src/osmo-nitb/Makefile.am M openbsc/src/utils/Makefile.am M openbsc/tests/Makefile.am M openbsc/tests/abis/Makefile.am M openbsc/tests/bsc-nat/Makefile.am M openbsc/tests/bsc/Makefile.am M openbsc/tests/channel/Makefile.am M openbsc/tests/db/Makefile.am M openbsc/tests/gbproxy/Makefile.am M openbsc/tests/gsm0408/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mgcp/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/oap/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/smpp/Makefile.am M openbsc/tests/subscr/Makefile.am M openbsc/tests/trau/Makefile.am M openbsc/tests/xid/Makefile.am 37 files changed, 1,481 insertions(+), 471 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/838/4 diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am index 8696eb4..f7eda56 100644 --- a/openbsc/Makefile.am +++ b/openbsc/Makefile.am @@ -1,7 +1,16 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = doc include src tests +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +SUBDIRS = \ + doc \ + include \ + src \ + tests \ + $(NULL) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = openbsc.pc diff --git a/openbsc/doc/Makefile.am b/openbsc/doc/Makefile.am index aee2d7b..5a23107 100644 --- a/openbsc/doc/Makefile.am +++ b/openbsc/doc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = examples +SUBDIRS = \ + examples \ + $(NULL) diff --git a/openbsc/doc/examples/Makefile.am b/openbsc/doc/examples/Makefile.am index 8f14fdc..530c3fa 100644 --- a/openbsc/doc/examples/Makefile.am +++ b/openbsc/doc/examples/Makefile.am @@ -1,4 +1,3 @@ - CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' dist-hook: diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index 4596b6e..3234e62 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,8 @@ -SUBDIRS = openbsc +SUBDIRS = \ + openbsc \ + $(NULL) -noinst_HEADERS = mISDNif.h compat_af_isdn.h +noinst_HEADERS = \ + mISDNif.h \ + compat_af_isdn.h \ + $(NULL) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..cae8ba4 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -1,25 +1,87 @@ -noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ - gsm_subscriber.h gsm_04_11.h debug.h signal.h \ - misdn.h chan_alloc.h paging.h ctrl.h \ - trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ - silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h \ - vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \ - handover_decision.h rrlp.h \ - crc24.h gprs_llc.h gprs_gmm.h \ - gb_proxy.h gprs_sgsn.h sgsn.h \ - auth.h osmo_msc.h bsc_msc.h bsc_nat.h \ - osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \ - osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.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_client.h bsc_msg_filter.h \ - oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ - iu.h +noinst_HEADERS = \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bss.h \ + chan_alloc.h \ + crc24.h \ + ctrl.h \ + db.h \ + debug.h \ + e1_config.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_gsup_client.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp.h \ + gprs_utils.h \ + gsm_04_08.h \ + gsm_04_11.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + gtphub.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ + iu.h \ + meas_feed.h \ + meas_rep.h \ + mgcp.h \ + mgcp_internal.h \ + mgcp_transcode.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + nat_rewrite_trie.h \ + network_listen.h \ + oap.h \ + oap_messages.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_msc_data.h \ + osmux.h \ + paging.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + smpp.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + token_auth.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + $(NULL) -openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h -openbscdir = $(includedir)/openbsc +openbsc_HEADERS = \ + bsc_api.h \ + gsm_04_08.h \ + meas_rep.h \ + $(NULL) + +openbscdir = \ + $(includedir)/openbsc \ + $(NULL) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 4aa880f..272292a 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -1,22 +1,59 @@ -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) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) # Libraries -SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter +SUBDIRS = \ + libcommon \ + libmgcp \ + libbsc \ + libmsc \ + libtrau \ + libfilter \ + $(NULL) # Conditional Libraries if BUILD_IU -SUBDIRS += libiu +SUBDIRS += \ + libiu \ + $(NULL) endif # Programs -SUBDIRS += osmo-nitb osmo-bsc_mgcp utils ipaccess gprs +SUBDIRS += \ + osmo-nitb \ + osmo-bsc_mgcp \ + utils \ + ipaccess \ + gprs \ + $(NULL) # Conditional Programs if BUILD_NAT -SUBDIRS += osmo-bsc_nat +SUBDIRS += \ + osmo-bsc_nat \ + $(NULL) endif + if BUILD_BSC -SUBDIRS += osmo-bsc +SUBDIRS += \ + osmo-bsc \ + $(NULL) endif diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..02c8878 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -1,50 +1,126 @@ -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) \ - $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(NULL) -bin_PROGRAMS = osmo-gbproxy - +bin_PROGRAMS = \ + osmo-gbproxy \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -bin_PROGRAMS += osmo-sgsn osmo-gtphub +bin_PROGRAMS += \ + osmo-sgsn \ + osmo-gtphub \ + $(NULL) endif endif -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) $(LIBCRYPTO_LIBS) -lrt +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 \ + $(NULL) +osmo_gbproxy_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) -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_utils.c gprs_gsup_client.c \ - sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +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_utils.c \ + gprs_gsup_client.c \ + sgsn_cdr.c \ + sgsn_ares.c \ + oap.c \ + oap_messages.c \ + gprs_llc_xid.c \ + $(NULL) +osmo_sgsn_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif -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 +osmo_gtphub_SOURCES = \ + gtphub_main.c \ + gtphub.c \ + gtphub_sock.c \ + gtphub_ares.c \ + gtphub_vty.c \ + sgsn_ares.c \ + gprs_utils.c \ + $(NULL) +osmo_gtphub_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCARES_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am index 9acc0f7..784a578 100644 --- a/openbsc/src/ipaccess/Makefile.am +++ b/openbsc/src/ipaccess/Makefile.am @@ -1,26 +1,66 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = abisip-find ipaccess-config ipaccess-proxy +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -abisip_find_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) -abisip_find_SOURCES = abisip-find.c +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -ipaccess_config_SOURCES = ipaccess-config.c ipaccess-firmware.c network_listen.c +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +bin_PROGRAMS = \ + abisip-find \ + ipaccess-config \ + ipaccess-proxy \ + $(NULL) + +abisip_find_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) + +abisip_find_SOURCES = \ + abisip-find.c \ + $(NULL) + +ipaccess_config_SOURCES = \ + ipaccess-config.c \ + ipaccess-firmware.c \ + network_listen.c \ + $(NULL) # FIXME: resolve the bogus dependencies patched around here: -ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBCRYPT) $(OSMO_LIBS) +ipaccess_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(OSMO_LIBS) \ + $(NULL) -ipaccess_proxy_SOURCES = ipaccess-proxy.c -ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) +ipaccess_proxy_SOURCES = \ + ipaccess-proxy.c \ + $(NULL) + +ipaccess_proxy_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am index fd8de0e..4728e23 100644 --- a/openbsc/src/libbsc/Makefile.am +++ b/openbsc/src/libbsc/Makefile.am @@ -1,28 +1,53 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libbsc.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libbsc_a_SOURCES = abis_nm.c abis_nm_vty.c \ - abis_om2000.c abis_om2000_vty.c \ - abis_rsl.c bsc_rll.c \ - paging.c \ - bts_ericsson_rbs2000.c \ - bts_ipaccess_nanobts.c \ - bts_siemens_bs11.c \ - bts_nokia_site.c \ - bts_unknown.c \ - bts_sysmobts.c \ - chan_alloc.c \ - handover_decision.c handover_logic.c meas_rep.c \ - rest_octets.c system_information.c \ - e1_config.c \ - bsc_api.c bsc_msc.c bsc_vty.c \ - gsm_04_08_utils.c \ - bsc_init.c bts_init.c bsc_rf_ctrl.c \ - arfcn_range_encode.c bsc_ctrl_commands.c \ - bsc_ctrl_lookup.c \ - net_init.c \ - bsc_dyn_ts.c +noinst_LIBRARIES = \ + libbsc.a \ + $(NULL) + +libbsc_a_SOURCES = \ + abis_nm.c \ + abis_nm_vty.c \ + abis_om2000.c \ + abis_om2000_vty.c \ + abis_rsl.c \ + bsc_rll.c \ + paging.c \ + bts_ericsson_rbs2000.c \ + bts_ipaccess_nanobts.c \ + bts_siemens_bs11.c \ + bts_nokia_site.c \ + bts_unknown.c \ + bts_sysmobts.c \ + chan_alloc.c \ + handover_decision.c \ + handover_logic.c \ + meas_rep.c \ + rest_octets.c \ + system_information.c \ + e1_config.c \ + bsc_api.c \ + bsc_msc.c bsc_vty.c \ + gsm_04_08_utils.c \ + bsc_init.c \ + bts_init.c \ + bsc_rf_ctrl.c \ + arfcn_range_encode.c \ + bsc_ctrl_commands.c \ + bsc_ctrl_lookup.c \ + net_init.c \ + bsc_dyn_ts.c \ + $(NULL) diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am index 75f40ee..6cfebc2 100644 --- a/openbsc/src/libcommon/Makefile.am +++ b/openbsc/src/libcommon/Makefile.am @@ -1,9 +1,29 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libcommon.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \ - gsm_data_shared.c socket.c talloc_ctx.c \ - gsm_subscriber_base.c +noinst_LIBRARIES = \ + libcommon.a \ + $(NULL) + +libcommon_a_SOURCES = \ + bsc_version.c \ + common_vty.c \ + debug.c \ + gsm_data.c \ + gsm_data_shared.c \ + socket.c \ + talloc_ctx.c \ + gsm_subscriber_base.c \ + $(NULL) diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am index ed3cd43..6d3db0b 100644 --- a/openbsc/src/libfilter/Makefile.am +++ b/openbsc/src/libfilter/Makefile.am @@ -1,11 +1,26 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libfilter.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libfilter.a \ + $(NULL) libfilter_a_SOURCES = \ bsc_msg_filter.c \ bsc_msg_acc.c \ - bsc_msg_vty.c + bsc_msg_vty.c \ + $(NULL) diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..e5f9e27 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,10 +1,28 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libiu.a +noinst_LIBRARIES = \ + libiu.a \ + $(NULL) -libiu_a_SOURCES = iu.c iu_vty.c +libiu_a_SOURCES = \ + iu.c \ + iu_vty.c \ + $(NULL) diff --git a/openbsc/src/libmgcp/Makefile.am b/openbsc/src/libmgcp/Makefile.am index 4403d60..5faf602 100644 --- a/openbsc/src/libmgcp/Makefile.am +++ b/openbsc/src/libmgcp/Makefile.am @@ -1,16 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(COVERAGE_LDFLAGS) $(LIBBCG729_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libmgcp.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_HEADERS = g711common.h +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBBCG729_LIBS) \ + $(NULL) -libmgcp_a_SOURCES = mgcp_protocol.c mgcp_network.c mgcp_vty.c mgcp_osmux.c \ - mgcp_sdp.c +noinst_LIBRARIES = \ + libmgcp.a \ + $(NULL) +noinst_HEADERS = \ + g711common.h \ + $(NULL) + +libmgcp_a_SOURCES = \ + mgcp_protocol.c \ + mgcp_network.c \ + mgcp_vty.c \ + mgcp_osmux.c \ + mgcp_sdp.c \ + $(NULL) if BUILD_MGCP_TRANSCODING - libmgcp_a_SOURCES += mgcp_transcode.c +libmgcp_a_SOURCES += \ + mgcp_transcode.c \ + $(NULL) endif diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index 5195890..d236d3a 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -1,27 +1,59 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_feed.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libmsc.a +noinst_HEADERS = \ + meas_feed.h \ + $(NULL) -libmsc_a_SOURCES = auth.c \ - db.c \ - gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c mncc_builtin.c mncc_sock.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - token_auth.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c ctrl_commands.c meas_feed.c +noinst_LIBRARIES = \ + libmsc.a \ + $(NULL) + +libmsc_a_SOURCES = \ + auth.c \ + db.c \ + gsm_04_08.c \ + gsm_04_11.c \ + gsm_04_11_helper.c \ + gsm_04_80.c \ + gsm_subscriber.c \ + mncc.c \ + mncc_builtin.c \ + mncc_sock.c \ + rrlp.c \ + silent_call.c \ + sms_queue.c \ + token_auth.c \ + ussd.c \ + vty_interface_layer3.c \ + transaction.c \ + osmo_msc.c \ + ctrl_commands.c \ + meas_feed.c \ + $(NULL) if BUILD_SMPP -noinst_HEADERS += smpp_smsc.h -libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c +noinst_HEADERS += \ + smpp_smsc.h \ + $(NULL) + +libmsc_a_SOURCES += \ + smpp_smsc.c \ + smpp_openbsc.c \ + smpp_vty.c \ + smpp_utils.c \ + $(NULL) endif diff --git a/openbsc/src/libtrau/Makefile.am b/openbsc/src/libtrau/Makefile.am index 0fe3a53..46becd6 100644 --- a/openbsc/src/libtrau/Makefile.am +++ b/openbsc/src/libtrau/Makefile.am @@ -1,7 +1,31 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libtrau.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libtrau_a_SOURCES = rtp_proxy.c trau_mux.c trau_upqueue.c +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libtrau.a \ + $(NULL) + +libtrau_a_SOURCES = \ + rtp_proxy.c \ + trau_mux.c \ + trau_upqueue.c \ + $(NULL) diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 4aa1803..2dbfeb8 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -1,21 +1,55 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ - osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c +bin_PROGRAMS = \ + osmo-bsc \ + $(NULL) + +osmo_bsc_SOURCES = \ + osmo_bsc_main.c \ + osmo_bsc_vty.c \ + osmo_bsc_api.c \ + osmo_bsc_grace.c \ + osmo_bsc_msc.c \ + osmo_bsc_sccp.c \ + osmo_bsc_filter.c \ + osmo_bsc_bssap.c \ + osmo_bsc_audio.c \ + osmo_bsc_ctrl.c \ + $(NULL) + # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_mgcp/Makefile.am b/openbsc/src/osmo-bsc_mgcp/Makefile.am index a48f24b..a19a4eb 100644 --- a/openbsc/src/osmo-bsc_mgcp/Makefile.am +++ b/openbsc/src/osmo-bsc_mgcp/Makefile.am @@ -1,14 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_mgcp +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -osmo_bsc_mgcp_SOURCES = mgcp_main.c +bin_PROGRAMS = \ + osmo-bsc_mgcp \ + $(NULL) -osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libmgcp/libmgcp.a -lrt \ - $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(LIBBCG729_LIBS) \ - $(LIBRARY_GSM) +osmo_bsc_mgcp_SOURCES = \ + mgcp_main.c \ + $(NULL) + +osmo_bsc_mgcp_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_nat/Makefile.am b/openbsc/src/osmo-bsc_nat/Makefile.am index 4a6f74d..6027f27 100644 --- a/openbsc/src/osmo-bsc_nat/Makefile.am +++ b/openbsc/src/osmo-bsc_nat/Makefile.am @@ -1,19 +1,57 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBCRYPTO_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_nat +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_bsc_nat_SOURCES = bsc_filter.c bsc_mgcp_utils.c bsc_nat.c bsc_nat_utils.c \ - bsc_nat_vty.c bsc_sccp.c bsc_ussd.c bsc_nat_ctrl.c \ - bsc_nat_rewrite.c bsc_nat_rewrite_trie.c bsc_nat_filter.c +bin_PROGRAMS = \ + osmo-bsc_nat \ + $(NULL) + +osmo_bsc_nat_SOURCES = \ + bsc_filter.c \ + bsc_mgcp_utils.c \ + bsc_nat.c \ + bsc_nat_utils.c \ + bsc_nat_vty.c \ + bsc_sccp.c \ + bsc_ussd.c \ + bsc_nat_ctrl.c \ + bsc_nat_rewrite.c \ + bsc_nat_rewrite_trie.c \ + bsc_nat_filter.c \ + $(NULL) + osmo_bsc_nat_LDADD = \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libfilter/libfilter.a \ - -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-nitb/Makefile.am b/openbsc/src/osmo-nitb/Makefile.am index 3b7cc8d..60514c0 100644 --- a/openbsc/src/osmo-nitb/Makefile.am +++ b/openbsc/src/osmo-nitb/Makefile.am @@ -1,18 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = osmo-nitb +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_nitb_SOURCES = bsc_hack.c +bin_PROGRAMS = \ + osmo-nitb \ + $(NULL) + +osmo_nitb_SOURCES = \ + bsc_hack.c \ + $(NULL) + osmo_nitb_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - -ldbi $(LIBCRYPT) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOABIS_LIBS) $(LIBSMPP34_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..0dbb85c 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,42 +1,123 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ - $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_db.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = bs11_config isdnsync +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + meas_db.h \ + $(NULL) + +bin_PROGRAMS = \ + bs11_config \ + isdnsync \ + $(NULL) if HAVE_SQLITE3 -bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db +bin_PROGRAMS += \ + osmo-meas-pcap2db \ + osmo-meas-udp2db \ + $(NULL) endif if HAVE_LIBCDK -bin_PROGRAMS += meas_vis +bin_PROGRAMS += \ + meas_vis \ + $(NULL) endif if BUILD_SMPP -noinst_PROGRAMS = smpp_mirror +noinst_PROGRAMS = \ + smpp_mirror \ + $(NULL) endif -bs11_config_SOURCES = bs11_config.c -bs11_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +bs11_config_SOURCES = \ + bs11_config.c \ + $(NULL) -isdnsync_SOURCES = isdnsync.c +bs11_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) -smpp_mirror_SOURCES = smpp_mirror.c -smpp_mirror_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) +isdnsync_SOURCES = \ + isdnsync.c \ + $(NULL) -meas_vis_SOURCES = meas_vis.c -meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses -meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_SOURCES = \ + smpp_mirror.c \ + $(NULL) -osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c -osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS) -osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(NULL) -osmo_meas_udp2db_SOURCES = meas_udp2db.c meas_db.c -osmo_meas_udp2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(SQLITE3_LIBS) -osmo_meas_udp2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_SOURCES = \ + meas_vis.c \ + $(NULL) + +meas_vis_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lcdk \ + -lncurses \ + $(NULL) + +meas_vis_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_pcap2db_SOURCES = \ + meas_pcap2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_pcap2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + -lpcap \ + $(NULL) + +osmo_meas_pcap2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_udp2db_SOURCES = \ + meas_udp2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_udp2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +osmo_meas_udp2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..7396c52 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,24 +1,44 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid - +SUBDIRS = \ + gsm0408 \ + db \ + channel \ + mgcp \ + gprs \ + abis \ + gbproxy \ + trau \ + subscr \ + mm_auth \ + xid \ + $(NULL) if BUILD_NAT -SUBDIRS += bsc-nat bsc-nat-trie +SUBDIRS += \ + bsc-nat \ + bsc-nat-trie \ + $(NULL) endif - if BUILD_BSC -SUBDIRS += bsc +SUBDIRS += \ + bsc \ + $(NULL) endif - if BUILD_SMPP -SUBDIRS += smpp +SUBDIRS += \ + smpp \ + $(NULL) endif - if HAVE_LIBGTP -SUBDIRS += gtphub -if HAVE_LIBCARES -SUBDIRS += sgsn oap -endif -endif +SUBDIRS += \ + gtphub \ + $(NULL) +if HAVE_LIBCARES +SUBDIRS += \ + sgsn \ + oap \ + $(NULL) +endif +endif # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -38,9 +58,20 @@ echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) vty_test_runner.py ctrl_test_runner.py smpp_test_runner.py +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + vty_test_runner.py \ + ctrl_test_runner.py \ + smpp_test_runner.py \ + $(NULL) + TESTSUITE = $(srcdir)/testsuite -DISTCLEANFILES = atconfig + +DISTCLEANFILES = \ + atconfig \ + $(NULL) if ENABLE_EXT_TESTS python-tests: $(BUILT_SOURCES) diff --git a/openbsc/tests/abis/Makefile.am b/openbsc/tests/abis/Makefile.am index c2e38de..cbc3e07 100644 --- a/openbsc/tests/abis/Makefile.am +++ b/openbsc/tests/abis/Makefile.am @@ -1,17 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = abis_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = abis_test +EXTRA_DIST = \ + abis_test.ok \ + $(NULL) -abis_test_SOURCES = abis_test.c +noinst_PROGRAMS = \ + abis_test \ + $(NULL) + +abis_test_SOURCES = \ + abis_test.c \ + $(NULL) abis_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 26e5500..fa55d27 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -1,26 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_nat_test.ok bsc_data.c barr.cfg barr_dup.cfg prefixes.csv +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_nat_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_nat_test_SOURCES = bsc_nat_test.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c +EXTRA_DIST = \ + bsc_nat_test.ok \ + bsc_data.c \ + barr.cfg \ + barr_dup.cfg \ + prefixes.csv \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_nat_test \ + $(NULL) + +bsc_nat_test_SOURCES = \ + bsc_nat_test.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c + bsc_nat_test_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) \ - $(LIBOSMOCTRL_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am index 8b786ff..ddfa437 100644 --- a/openbsc/tests/bsc/Makefile.am +++ b/openbsc/tests/bsc/Makefile.am @@ -1,18 +1,45 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_test_SOURCES = bsc_test.c \ - $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c -bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) +EXTRA_DIST = \ + bsc_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_test \ + $(NULL) + +bsc_test_SOURCES = \ + bsc_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(NULL) + +bsc_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am index 51b2f83..5654572 100644 --- a/openbsc/tests/channel/Makefile.am +++ b/openbsc/tests/channel/Makefile.am @@ -1,14 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = channel_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = channel_test +EXTRA_DIST = \ + channel_test.ok \ + $(NULL) -channel_test_SOURCES = channel_test.c +noinst_PROGRAMS = \ + channel_test \ + $(NULL) + +channel_test_SOURCES = \ + channel_test.c \ + $(NULL) + channel_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ - -ldbi $(LIBOSMOGSM_LIBS) $(LIBCRYPTO_LIBS) + $(LIBOSMOGSM_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am index be3af5f..c4da31c 100644 --- a/openbsc/tests/db/Makefile.am +++ b/openbsc/tests/db/Makefile.am @@ -1,17 +1,48 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = db_test.ok db_test.err hlr.sqlite3 +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = db_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -db_test_SOURCES = db_test.c -db_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBCRYPTO_LIBS) -ldbi +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + hlr.sqlite3 \ + $(NULL) + +noinst_PROGRAMS = \ + db_test \ + $(NULL) + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gbproxy/Makefile.am b/openbsc/tests/gbproxy/Makefile.am index 18d77a8..2dd66df 100644 --- a/openbsc/tests/gbproxy/Makefile.am +++ b/openbsc/tests/gbproxy/Makefile.am @@ -1,27 +1,54 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gbproxy_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = gbproxy_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -gbproxy_test_SOURCES = gbproxy_test.c +EXTRA_DIST = \ + gbproxy_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + gbproxy_test \ + $(NULL) + +gbproxy_test_SOURCES = \ + gbproxy_test.c \ + $(NULL) + gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes + -Wl,--wrap=RAND_bytes \ + $(NULL) + gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) -lrt + $(top_builddir)/src/gprs/gb_proxy.o \ + $(top_builddir)/src/gprs/gb_proxy_patch.o \ + $(top_builddir)/src/gprs/gb_proxy_peer.o \ + $(top_builddir)/src/gprs/gb_proxy_tlli.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBRARY_DL) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index 79fb9f1..11fa6b9 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -1,12 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -noinst_PROGRAMS = gsm0408_test +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gsm0408_test.ok +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -gsm0408_test_SOURCES = gsm0408_test.c -gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) -ldbi +noinst_PROGRAMS = \ + gsm0408_test \ + $(NULL) + +EXTRA_DIST = \ + gsm0408_test.ok \ + $(NULL) + +gsm0408_test_SOURCES = \ + gsm0408_test.c \ + $(NULL) + +gsm0408_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..137924d 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,24 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) EXTRA_DIST = \ - gtphub_test.ok + gtphub_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = gtphub_test +noinst_PROGRAMS = \ + gtphub_test \ + $(NULL) endif endif -gtphub_test_SOURCES = gtphub_test.c +gtphub_test_SOURCES = \ + gtphub_test.c \ + $(NULL) + gtphub_test_LDFLAGS = \ -Wl,--wrap=gtphub_resolve_ggsn_addr \ -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write + -Wl,--wrap=gtphub_write \ + $(NULL) gtphub_test_LDADD = \ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt - + -lgtp \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 82d6ac6..4b18036 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -1,30 +1,72 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_FLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir) \ + $(NULL) -EXTRA_DIST = mgcp_test.ok mgcp_transcoding_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_FLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = mgcp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) +EXTRA_DIST = \ + mgcp_test.ok \ + mgcp_transcoding_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + mgcp_test \ + $(NULL) if BUILD_MGCP_TRANSCODING -noinst_PROGRAMS += mgcp_transcoding_test +noinst_PROGRAMS += \ + mgcp_transcoding_test \ + $(NULL) endif -mgcp_test_SOURCES = mgcp_test.c +mgcp_test_SOURCES = \ + mgcp_test.c \ + $(NULL) -mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) +mgcp_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + -lrt \ + -lm \ + $(NULL) -mgcp_transcoding_test_SOURCES = mgcp_transcoding_test.c +mgcp_transcoding_test_SOURCES = \ + mgcp_transcoding_test.c \ + $(NULL) mgcp_transcoding_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBBCG729_LIBS) -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) $(LIBRARY_GSM) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + -lm \ + $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..7eb14fa 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -1,21 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -noinst_PROGRAMS = mm_auth_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(NULL) -EXTRA_DIST = mm_auth_test.ok +noinst_PROGRAMS = \ + mm_auth_test \ + $(NULL) -mm_auth_test_SOURCES = mm_auth_test.c +EXTRA_DIST = \ + mm_auth_test.ok \ + $(NULL) + +mm_auth_test_SOURCES = \ + mm_auth_test.c \ + $(NULL) mm_auth_test_LDFLAGS = \ -Wl,--wrap=db_get_authinfo_for_subscr \ -Wl,--wrap=db_get_lastauthtuple_for_subscr \ - -Wl,--wrap=db_sync_lastauthtuple_for_subscr + -Wl,--wrap=db_sync_lastauthtuple_for_subscr \ + $(NULL) -mm_auth_test_LDADD = $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) +mm_auth_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/oap/Makefile.am b/openbsc/tests/oap/Makefile.am index 538e178..06ccf33 100644 --- a/openbsc/tests/oap/Makefile.am +++ b/openbsc/tests/oap/Makefile.am @@ -1,15 +1,30 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = oap_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + oap_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = oap_test +noinst_PROGRAMS = \ + oap_test \ + $(NULL) endif endif -oap_test_SOURCES = oap_test.c +oap_test_SOURCES = \ + oap_test.c \ + $(NULL) oap_test_LDADD = \ $(top_builddir)/src/gprs/oap.o \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..6371707 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,20 +1,42 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -EXTRA_DIST = sgsn_test.ok +EXTRA_DIST = \ + sgsn_test.ok \ + $(NULL) -noinst_PROGRAMS = sgsn_test +noinst_PROGRAMS = \ + sgsn_test \ + $(NULL) -sgsn_test_SOURCES = sgsn_test.c +sgsn_test_SOURCES = \ + sgsn_test.c \ + $(NULL) + sgsn_test_LDFLAGS = \ -Wl,--wrap=RAND_bytes \ -Wl,--wrap=sgsn_update_subscriber_data \ -Wl,--wrap=gprs_subscr_request_update_location \ -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gprs_gsup_client_send + -Wl,--wrap=gprs_gsup_client_send \ + $(NULL) sgsn_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_parse.o \ @@ -33,7 +55,7 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -41,12 +63,14 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + -lgtp \ + -lrt \ + $(NULL) if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) + $(LIBASN1C_LIBS) \ + $(NULL) endif - diff --git a/openbsc/tests/smpp/Makefile.am b/openbsc/tests/smpp/Makefile.am index aab4de9..5082707 100644 --- a/openbsc/tests/smpp/Makefile.am +++ b/openbsc/tests/smpp/Makefile.am @@ -1,13 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/libmsc \ + $(NULL) -EXTRA_DIST = smpp_test.ok smpp_test.err +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = smpp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -smpp_test_SOURCES = smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c +EXTRA_DIST = \ + smpp_test.ok \ + smpp_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + smpp_test \ + $(NULL) + +smpp_test_SOURCES = \ + smpp_test.c \ + $(top_builddir)/src/libmsc/smpp_utils.c \ + $(NULL) + smpp_test_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/subscr/Makefile.am b/openbsc/tests/subscr/Makefile.am index 4f96dc9..fb863d8 100644 --- a/openbsc/tests/subscr/Makefile.am +++ b/openbsc/tests/subscr/Makefile.am @@ -1,18 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = subscr_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = subscr_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -subscr_test_SOURCES = subscr_test.c -subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -# -ldbi +EXTRA_DIST = \ + subscr_test.ok \ + $(NULL) +noinst_PROGRAMS = \ + subscr_test \ + $(NULL) + +subscr_test_SOURCES = \ + subscr_test.c \ + $(NULL) + +subscr_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(NULL) diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am index cc1b4ef..93ce88e 100644 --- a/openbsc/tests/trau/Makefile.am +++ b/openbsc/tests/trau/Makefile.am @@ -1,17 +1,46 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = trau_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = trau_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -trau_test_SOURCES = trau_test.c -trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBRARY_DL) -ldbi +EXTRA_DIST = \ + trau_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + trau_test \ + $(NULL) + +trau_test_SOURCES = \ + trau_test.c \ + $(NULL) + +trau_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..e7c4cf0 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -1,11 +1,27 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = xid_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = xid_test +EXTRA_DIST = \ + xid_test.ok \ + $(NULL) -xid_test_SOURCES = xid_test.c +noinst_PROGRAMS = \ + xid_test \ + $(NULL) + +xid_test_SOURCES = \ + xid_test.c \ + $(NULL) xid_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ @@ -16,6 +32,8 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm - + -lgtp \ + -lrt \ + -lm \ + $(NULL) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 14:03:39 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Thu, 15 Sep 2016 14:03:39 +0000 Subject: [PATCH] openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/839 to look at the new patch set (#5). Build fixes Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 --- M openbsc/src/gprs/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 5 files changed, 10 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/839/5 diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 02c8878..59136bd 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -28,10 +28,12 @@ OSMO_LIBS = \ $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOGB_LIBS) \ + $(LIBGTP_LIBS) \ $(NULL) bin_PROGRAMS = \ @@ -121,6 +123,6 @@ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBCARES_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index 137924d..5c834b7 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -7,6 +7,8 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBGTP_CFLAGS) \ $(NULL) EXTRA_DIST = \ @@ -35,6 +37,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 7eb14fa..cb35198 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -6,6 +6,7 @@ AM_CFLAGS = \ -Wall \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCRYPTO_CFLAGS) \ $(NULL) diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 6371707..d148c48 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -7,6 +7,7 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCARES_CFLAGS) \ $(NULL) @@ -63,7 +64,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) if BUILD_IU diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index e7c4cf0..aaf17ed 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -32,7 +32,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ -lm \ $(NULL) -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 14:08:07 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 15 Sep 2016 14:08:07 +0000 Subject: [PATCH] osmo-bts[master]: Check Marker bit to send ONSET primitive to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#3). Check Marker bit to send ONSET primitive to L1 This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 8 files changed, 61 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/3 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..f2ee0a9 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Remove RTP hear Marker bit */ + marker = msgb_get_u8(resp_msg); + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Add RTP hear Marker bit */ + msgb_put_u8(msg, marker); /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..18a14ec 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..7dd4f95 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -88,7 +90,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..7ee503a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -288,6 +291,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -297,7 +301,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; uint8_t *l1_payload; @@ -327,9 +331,22 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + uint8_t cmr; + int8_t sti, cmi; + + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..0699834 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..47720d5 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -108,7 +110,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..fa262c2 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -385,6 +388,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -394,7 +398,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; uint8_t *l1_payload; @@ -426,9 +430,22 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + uint8_t cmr; + int8_t sti, cmi; + + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 15 17:27:10 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 15 Sep 2016 17:27:10 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix last SID save/repeat for lc15, sysmo In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/845 to look at the new patch set (#3). DTX: fix last SID save/repeat for lc15, sysmo Previously SID was incorrectly stored (with GSM Fn instead of timestamp) and, correspondingly, incorrectly retransmitted. Fix this by * storing timestamp (in ms) alongside with SID instead of Fn * using generic functions to save and repeat SID frames as necessary Note: this requires corresponding change in OpenBSC. Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Fixes: OS #1800, #1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 81 insertions(+), 136 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/845/3 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..f1a95c5 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -22,7 +22,9 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); + bool update); +uint8_t repeat_last_sid(const struct gsm_lchan *lchan, uint8_t *dst); +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..e4ca01e 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -97,20 +98,70 @@ } } +static inline time_t get_msec() +{ + struct timespec tspec; + clock_gettime(CLOCK_MONOTONIC, &tspec); + + return 1000 * tspec.tv_sec + tspec.tv_nsec / 1000000; +} + /* store the last SID frame in lchan context */ void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) + bool update) { size_t copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); + struct timespec tspec; + clock_gettime(CLOCK_MONOTONIC, &tspec); lchan->tch.last_sid.len = copy_len; - lchan->tch.last_sid.fn = fn; + lchan->tch.last_sid.msec = get_msec(); lchan->tch.last_sid.is_update = update; memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type) or 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(const struct gsm_lchan *lchan, uint8_t *dst) +{ + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + return lchan->tch.last_sid.len + 1; + } + LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + return 0; +} + +/*! \brief Check if enough time has passed since last SID (if any) to repeat it + * \param[in] lchan Logical channel on which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan) +{ + time_t delta = get_msec() - lchan->tch.last_sid.msec; + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 7) + return true; + return false; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 3) + return true; + return false; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..190d25f 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -270,14 +270,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, sti); return payload_len+1; } @@ -469,27 +463,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -512,30 +485,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -547,14 +503,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -562,14 +513,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..5b87220 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -367,14 +367,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, sti); return payload_len+1; } @@ -572,27 +566,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -615,30 +588,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -650,14 +606,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -665,14 +616,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 23:35:24 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 23:35:24 +0000 Subject: [PATCH] libosmocore[master]: msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_... Message-ID: Review at https://gerrit.osmocom.org/847 msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_ctx() So far each and every main() scope creates a msgb talloc context and either passes it to msgb_set_talloc_ctx() or sets tall_msgb_ctx directly (by defining it extern first). Remove some code duplication: add one central function that creates the "msgb" talloc context for all. Most users of msgb employ a talloc_named_const(), but osmo-bts uses a talloc_pool() instead. Offer both ways by means of the pool_size argument, and for both ways make sure the context is called "msgb". Suggest that msgb users should move to this new function: deprecate msgb_set_talloc_ctx(). To be able to do so, include core/defs.h in msgb.h. There's a tradeoff between hiding the msgb talloc context behind API that tries to guess all use cases versus avoiding code dup. This patch opts against code dup and boldly assumes that all future use is covered. Also, the new function suggests to not access tall_msgb_ctx directly, which can be considered a style improvement. It seems that not all main scopes that use msgb actually initialize the msgb ctx. As a fallback for these, explicitly initialize tall_msgb_ctx to NULL. Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c --- M include/osmocom/core/msgb.h M src/msgb.c 2 files changed, 24 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/47/847/1 diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 6f617e2..7c85771 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -23,6 +23,7 @@ #include #include #include +#include /*! \defgroup msgb Message buffers * @{ @@ -457,6 +458,8 @@ /* non inline functions to ease binding */ uint8_t *msgb_data(const struct msgb *msg); -void msgb_set_talloc_ctx(void *ctx); + +void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size); +void msgb_set_talloc_ctx(void *ctx) OSMO_DEPRECATED("Use msgb_talloc_ctx_init() instead"); /*! @} */ diff --git a/src/msgb.c b/src/msgb.c index ea8dc82..a27100c 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -35,7 +35,7 @@ #include //#include -void *tall_msgb_ctx; +void *tall_msgb_ctx = NULL; /*! \brief Allocate a new message buffer * \param[in] size Length in octets, including headroom @@ -151,6 +151,7 @@ } /*! \brief Set the talloc context for \ref msgb_alloc + * Deprecated, use msgb_talloc_ctx_init() instead. * \param[in] ctx talloc context to be used as root for msgb allocations */ void msgb_set_talloc_ctx(void *ctx) @@ -158,6 +159,24 @@ tall_msgb_ctx = ctx; } +/*! \brief Initialize a msgb talloc context for \ref msgb_alloc. + * Create a talloc context called "msgb". If \a pool_size is 0, create a named + * const as msgb talloc context. If \a pool_size is nonzero, create a talloc + * pool, possibly for faster msgb allocations (see talloc_pool()). + * \param[in] root_ctx talloc context used as parent for the new "msgb" ctx. + * \param[in] pool_size if nonzero, create a talloc pool of this size. + * \returns the new msgb talloc context, e.g. for reporting + */ +void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size) +{ + if (!pool_size) + tall_msgb_ctx = talloc_size(root_ctx, 0); + else + tall_msgb_ctx = talloc_pool(root_ctx, pool_size); + talloc_set_name_const(tall_msgb_ctx, "msgb"); + return tall_msgb_ctx; +} + /*! \brief Copy an msgb. * * This function allocates a new msgb, copies the data buffer of msg, -- To view, visit https://gerrit.osmocom.org/847 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 15 23:46:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 15 Sep 2016 23:46:19 +0000 Subject: osmo-bts[master]: Check Marker bit to send ONSET primitive to L1 In-Reply-To: References: Message-ID: Patch Set 3: I'm not sure what this patch is doing. Doesn't it simply _replace_ the AMR payload (of the RTP frame with marker bit) and send an ONSET instead? Remember, in case of the marker bit set, we need to send first a PH-DATA.req with ONSET, and then send another PH-DATA.req with the actual codec payload. -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 15 23:59:09 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 15 Sep 2016 23:59:09 +0000 Subject: [PATCH] osmo-bts[master]: sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty Message-ID: Review at https://gerrit.osmocom.org/848 sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty Instead of passing the msgb ctx to telnet_init(), pass the *mgr* ctx. Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f --- M src/osmo-bts-litecell15/misc/lc15bts_mgr.c M src/osmo-bts-sysmo/misc/sysmobts_mgr.c 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/48/848/1 diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c index 506e525..c97525c 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c @@ -249,7 +249,7 @@ exit(1); } - rc = telnet_init(tall_msgb_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index fce375b..ccb84d8 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -274,7 +274,7 @@ exit(1); } - rc = telnet_init(tall_msgb_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/848 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 00:44:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 00:44:01 +0000 Subject: [PATCH] osmo-iuh[master]: ranap: include port in RTP TransportLayerInformation Message-ID: Review at https://gerrit.osmocom.org/849 ranap: include port in RTP TransportLayerInformation Remove an #if 0 to properly include the port information (verified to work). Adjust test expectations. Change-Id: I45fb134959dea9bcdfbfd9d8a061e67c3cc80fb7 --- M src/ranap_msg_factory.c M src/tests/test-ranap.ok 2 files changed, 4 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/49/849/1 diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 695a6be..94eb1c5 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -653,14 +653,9 @@ RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); uint8_t binding_id[4]; -#if 0 binding_id[0] = port >> 8; binding_id[1] = port & 0xff; binding_id[2] = binding_id[3] = 0; -#else - binding_id[0] = binding_id[1] = binding_id[2] = 0; - binding_id[3] = 1; -#endif new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; diff --git a/src/tests/test-ranap.ok b/src/tests/test-ranap.ok index 841edad..2ad19e6 100644 --- a/src/tests/test-ranap.ok +++ b/src/tests/test-ranap.ok @@ -91,7 +91,7 @@ 38 02 D8 01 2F A7 20 2F A8 00 00 F4 4C 08 0A 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3C 40 00 00 00 50 3D 02 00 02 0D C0 35 00 - 01 0A 0B 0C 0D 40 00 00 00 01 + 01 0A 0B 0C 0D 40 09 26 00 00 00 @@ -103,11 +103,11 @@ 00 00 01 00 35 00 3A 38 02 D8 01 2F A7 20 2F A8 00 00 F4 4C 08 0A 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3C 40 00 00 00 50 3D - 02 00 02 0D C0 35 00 01 0A 0B 0C 0D 40 00 00 00 - 01 40 01 00 + 02 00 02 0D C0 35 00 01 0A 0B 0C 0D 40 09 26 00 + 00 40 01 00 -00 00 00 4b 00 00 01 00 36 40 44 00 00 01 00 35 00 3a 38 02 d8 01 2f a7 20 2f a8 00 00 f4 4c 08 0a 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3c 40 00 00 00 50 3d 02 00 02 0d c0 35 00 01 0a 0b 0c 0d 40 00 00 00 01 40 01 00 +00 00 00 4b 00 00 01 00 36 40 44 00 00 01 00 35 00 3a 38 02 d8 01 2f a7 20 2f a8 00 00 f4 4c 08 0a 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3c 40 00 00 00 50 3d 02 00 02 0d c0 35 00 01 0a 0b 0c 0d 40 09 26 00 00 40 01 00 ==> RAB ASSIGNMENT COMMAND (DATA) -- To view, visit https://gerrit.osmocom.org/849 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I45fb134959dea9bcdfbfd9d8a061e67c3cc80fb7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 00:56:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 00:56:00 +0000 Subject: libosmocore[master]: msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_... In-Reply-To: References: Message-ID: Patch Set 1: Various patches, among which the mscsplit and IuCS series, build on this. It would be nice to accept (or reject) this change rather sooner than later, so that the patch submissions can continue. -- To view, visit https://gerrit.osmocom.org/847 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: properly #include from gsm_subscriber.h Message-ID: Review at https://gerrit.osmocom.org/850 properly #include from gsm_subscriber.h Don't use quoted, local include, use <> style include. Cosmetic: also move stdbool.h include to the top to keep osmocom and openbsc includes grouped. Change-Id: Iaa3dc36768f96f6b8c91010a2ba389fdc37f1503 --- M openbsc/include/openbsc/gsm_subscriber.h 1 file changed, 3 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/50/850/1 diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 3d7c244..314d619 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -1,11 +1,12 @@ #ifndef _GSM_SUBSCR_H #define _GSM_SUBSCR_H -#include "gsm_data.h" +#include + #include #include -#include +#include #define GSM_NAME_LENGTH 160 -- To view, visit https://gerrit.osmocom.org/850 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaa3dc36768f96f6b8c91010a2ba389fdc37f1503 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: remove unused bsc_copyright from bsc_vty.c Message-ID: Review at https://gerrit.osmocom.org/851 remove unused bsc_copyright from bsc_vty.c Change-Id: I281791c0f57ca75ffe14431a3030811b2d224f0b --- M openbsc/src/libbsc/bsc_vty.c 1 file changed, 0 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/51/851/1 diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 8116af1..cf3ce53 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -3991,7 +3991,6 @@ } extern int bsc_vty_init_extra(void); -extern const char *openbsc_copyright; int bsc_vty_init(const struct log_info *cat) { -- To view, visit https://gerrit.osmocom.org/851 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I281791c0f57ca75ffe14431a3030811b2d224f0b Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: vty l3 help: fix typo 'comamnds'; fix english s/his// Message-ID: Review at https://gerrit.osmocom.org/852 vty l3 help: fix typo 'comamnds'; fix english s/his// Change-Id: I6be52bbb69de8aa0a6d57a3a320661ad85fc2cc4 --- M openbsc/src/libmsc/vty_interface_layer3.c 1 file changed, 5 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/52/852/1 diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index e7ff0a9..fd3771a 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -141,7 +141,7 @@ DEFUN(sms_send_pend, sms_send_pend_cmd, "sms send pending", - "SMS related comamnds\n" "SMS Sending related commands\n" + "SMS related commands\n" "SMS Sending related commands\n" "Send all pending SMS") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); @@ -199,10 +199,10 @@ } #define SUBSCR_TYPES "(extension|imsi|tmsi|id)" #define SUBSCR_HELP "Operations on a Subscriber\n" \ - "Identify subscriber by his extension (phone number)\n" \ - "Identify subscriber by his IMSI\n" \ - "Identify subscriber by his TMSI\n" \ - "Identify subscriber by his database ID\n" \ + "Identify subscriber by extension (phone number)\n" \ + "Identify subscriber by IMSI\n" \ + "Identify subscriber by TMSI\n" \ + "Identify subscriber by database ID\n" \ "Identifier for the subscriber\n" DEFUN(show_subscr, -- To view, visit https://gerrit.osmocom.org/852 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6be52bbb69de8aa0a6d57a3a320661ad85fc2cc4 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS Message-ID: Review at https://gerrit.osmocom.org/853 utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 --- M openbsc/src/utils/Makefile.am 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/53/853/1 diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..7b966ff 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ $(LIBSMPP34_CFLAGS) AM_LDFLAGS = $(COVERAGE_LDFLAGS) -- To view, visit https://gerrit.osmocom.org/853 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: cosmetic: various comment, whitespace tweaks Message-ID: Review at https://gerrit.osmocom.org/854 cosmetic: various comment, whitespace tweaks Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libmsc/gsm_04_08.c M openbsc/tests/bsc/bsc_test.c 4 files changed, 5 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/54/854/1 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..d50b187 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -103,7 +103,7 @@ uint8_t last_seen_nr; }; -/* the per subscriber data for lchan */ +/* mobile subscriber data */ struct gsm_subscriber_connection { struct llist_head entry; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index ce2e9b7..4ae2585 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -381,7 +381,7 @@ 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; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c30fbb0..680ce93 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1088,7 +1088,7 @@ if (subscr) { subscr_update(subscr, bts, - GSM_SUBSCRIBER_UPDATE_DETACHED); + GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr)); subscr->equipment.classmark1 = idi->classmark1; @@ -3657,7 +3657,7 @@ return 0; } -/* here we get data from the BSC level... */ +/* Main entry point for receiving data from the BSC|RNC level. */ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); diff --git a/openbsc/tests/bsc/bsc_test.c b/openbsc/tests/bsc/bsc_test.c index d032f61..cc45652 100644 --- a/openbsc/tests/bsc/bsc_test.c +++ b/openbsc/tests/bsc/bsc_test.c @@ -139,7 +139,7 @@ conn->bts = bts; conn->sccp_con = sccp_con; - /* start testinh with proper messages */ + /* start testing with proper messages */ printf("Testing BTS<->MSC message scan.\n"); for (i = 0; i < ARRAY_SIZE(test_scan_defs); ++i) { const struct test_definition *test_def = &test_scan_defs[i]; -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: Sanity fixes for gsm0408_dispatch(): rc, assertions Message-ID: Review at https://gerrit.osmocom.org/855 Sanity fixes for gsm0408_dispatch(): rc, assertions gsm0408_dispatch() is the main entry point for receiving data from the BSC/RNC level, so make sure callers pass valid pointers before using them all the way down the code path (related to CID#93769, a fix before this was refactored). For unknown/unimplemented packet discriminators, make sure to return error codes. Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 --- M openbsc/src/libmsc/gsm_04_08.c 1 file changed, 5 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/55/855/1 diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 680ce93..95994a4 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -3664,6 +3664,9 @@ uint8_t pdisc = gsm48_hdr_pdisc(gh); int rc = 0; + OSMO_ASSERT(conn); + OSMO_ASSERT(msg); + LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message, pdisc=%d\n", pdisc); if (silent_call_reroute(conn, msg)) return silent_call_rx(conn, msg); @@ -3687,6 +3690,7 @@ case GSM48_PDISC_SM_GPRS: LOGP(DRLL, LOGL_NOTICE, "Unimplemented " "GSM 04.08 discriminator 0x%02x\n", pdisc); + rc = -ENOTSUP; break; case GSM48_PDISC_NC_SS: release_anchor(conn); @@ -3695,6 +3699,7 @@ default: LOGP(DRLL, LOGL_NOTICE, "Unknown " "GSM 04.08 discriminator 0x%02x\n", pdisc); + rc = -EINVAL; break; } -- To view, visit https://gerrit.osmocom.org/855 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:23:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:23:19 +0000 Subject: [PATCH] openbsc[master]: debug log for sms: fix/add Message-ID: Review at https://gerrit.osmocom.org/856 debug log for sms: fix/add One logged the wrong function name. Add others. Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 --- M openbsc/src/libmsc/gsm_04_11.c M openbsc/src/libmsc/sms_queue.c M openbsc/src/libmsc/vty_interface_layer3.c 3 files changed, 14 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/56/856/1 diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 6d3f41b..004dd0d 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -879,7 +879,7 @@ return -EBUSY; } - DEBUGP(DLSMS, "send_sms_lchan()\n"); + DEBUGP(DLSMS, "gsm411_send_sms()\n"); /* FIXME: allocate transaction with message reference */ trans = trans_alloc(conn->bts->network, conn->subscr, @@ -987,10 +987,14 @@ * if yes, send the SMS this way */ conn = connection_for_subscr(subscr); if (conn) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS via already open connection %p to %s\n", + conn, subscr_name(subscr)); return gsm411_send_sms(conn, sms); } /* if not, we have to start paging */ + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n", + subscr_name(subscr)); res = subscr_request_channel(subscr, RSL_CHANNEED_SDCCH, paging_cb_send_sms, sms); if (!res) { diff --git a/openbsc/src/libmsc/sms_queue.c b/openbsc/src/libmsc/sms_queue.c index 5dbe81f..ebc53c2 100644 --- a/openbsc/src/libmsc/sms_queue.c +++ b/openbsc/src/libmsc/sms_queue.c @@ -225,10 +225,14 @@ sms = take_next_sms(smsq); - if (!sms) + if (!sms) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (%d attempted)\n", + attempted); break; + } rounds += 1; + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds); /* * This code needs to detect a loop. It assumes that no SMS @@ -243,6 +247,8 @@ first_sub = sms->receiver->id; initialized = 1; } else if (first_sub == sms->receiver->id) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (loop) (%d attempted)\n", + attempted); sms_free(sms); break; } @@ -324,6 +330,7 @@ */ int sms_queue_trigger(struct gsm_sms_queue *smsq) { + LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n"); if (osmo_timer_pending(&smsq->push_queue)) return 0; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index fd3771a..6f0006c 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -176,6 +176,7 @@ sms_free(sms); return CMD_WARNING; } + LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n"); sms_free(sms); sms_queue_trigger(receiver->group->net->sms_queue); -- To view, visit https://gerrit.osmocom.org/856 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:34:43 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:34:43 +0000 Subject: osmo-bts[master]: sysmo: Fix build error for sysmobts target In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (adding weight to my previous comment) -- To view, visit https://gerrit.osmocom.org/814 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29e9bf8db483376cdf5084658a738f1589622e53 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:47:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:47:32 +0000 Subject: osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: Patch Set 9: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:54:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:54:01 +0000 Subject: [PATCH] openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/551 to look at the new patch set (#7). sms: change rp err cause of smpp_try_deliver errors smpp_try_deliver could fail with rc < 0. In such cases don't send the MS the rp error sms rejected (cause 21). A rejected message should not be sent again. The spec 04 11 recommends sending cause 41 Temporary failure in unknown cases. Add also a log message and rate counter for such cases. Tweaked-By: Neels Hofmeyr Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libmsc/gsm_04_11.c 2 files changed, 15 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/51/551/7 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..939e0ee 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -198,6 +198,7 @@ MSC_CTR_SMS_DELIVERED, MSC_CTR_SMS_RP_ERR_MEM, MSC_CTR_SMS_RP_ERR_OTHER, + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR, MSC_CTR_CALL_MO_SETUP, MSC_CTR_CALL_MO_CONNECT_ACK, MSC_CTR_CALL_MT_SETUP, @@ -216,6 +217,7 @@ [MSC_CTR_SMS_DELIVERED] = {"sms.delivered", "Global SMS Deliver attempts."}, [MSC_CTR_SMS_RP_ERR_MEM] = {"sms.rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."}, [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms.rp_err_other", "Other error of MS responses on a sms delive attempt."}, + [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "Unknown error occured during sms delivery."}, /* FIXME: count also sms delivered */ [MSC_CTR_CALL_MO_SETUP] = {"call.mo_setup", "Received setup requests from a MS to init a MO call."}, [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 6d3f41b..d1fdfb9 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -294,8 +295,12 @@ if (rc == 1) goto try_local; if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } return rc; } @@ -319,8 +324,12 @@ rc = 1; /* cause 1: unknown subscriber */ rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); } else if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } #else rc = 1; /* cause 1: unknown subscriber */ -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:54:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:54:38 +0000 Subject: openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 01:57:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 01:57:28 +0000 Subject: osmo-bts[master]: Update parameters in osmo-bts-sysmo for 11bit RACH In-Reply-To: References: Message-ID: Patch Set 8: Isn't anyone going to submit this? It's been approved for several weeks. -- To view, visit https://gerrit.osmocom.org/434 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I93831ddfb3f31b637e6a576f23a9bb4557758582 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: bhargava_abhyankar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 02:00:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 02:00:01 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 I'd approve, but waiting for Holger or Harald to +2 -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 02:00:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 02:00:37 +0000 Subject: openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 02:06:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 16 Sep 2016 02:06:11 +0000 Subject: [PATCH] osmo-pcu[master]: Revert "tbf: Add state WAIT_ASSIGN" In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/218 to look at the new patch set (#4). Revert "tbf: Add state WAIT_ASSIGN" This reverts commit f1a7b8fc6651f92a8b7f3f27b7ca05d07f4e44e0. Conflicts: tests/tbf/TbfTest.err The commit broke GPRS service at least for osmo-bts-sysmo on a SysmoBTS 1002 with current master of osmo-bts (ef30f50d5d6d5f863fc147d05ccdceb89284934e). The error observed is the following log output (was viewing both osmo-bts-sysmo and osmo-pcu logs interleaved): <0002> tbf.cpp:874 TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) T3169 timeout during transsmission <0002> tbf.cpp:893 - Assignment was on CCCH <0002> tbf.cpp:899 - No uplink data received yet <0007> l1sap.c:904 RACH for packet access <0001> pcu_l1_if.cpp:311 RACH request received: sapi=1 qta=0, ra=121, fn=13653 [repeat] When removing this single commit from current osmo-pcu master, GPRS service works well on SysmoBTS, with current osmo-bts master. The TbfTest.err expected output needed adjustment after the revert. Disclaimer: I am not aware of adverse effects this commit may have. I have no idea what the WAIT_ASSIGN state is used for -- further review is required. Change-Id: I1532f8e93194368cdc1e3846f82afa6d68cd5fbd --- M src/bts.cpp M src/tbf.cpp M src/tbf.h M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 5 files changed, 134 insertions(+), 191 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/18/218/4 diff --git a/src/bts.cpp b/src/bts.cpp index 795baa6..5fa988b 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -554,11 +554,8 @@ m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, m_bts.alpha, m_bts.gamma, -1); - if (plen >= 0) { + if (plen >= 0) pcu_l1if_tx_agch(immediate_assignment, plen); - if (tbf) - tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); - } bitvec_free(immediate_assignment); @@ -616,10 +613,8 @@ (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), tbf->trx->arfcn, ts, tbf->tsc(), 7, poll, tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1); - if (plen >= 0) { + if (plen >= 0) pcu_l1if_tx_pch(immediate_assignment, plen, imsi); - tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); - } bitvec_free(immediate_assignment); } diff --git a/src/tbf.cpp b/src/tbf.cpp index 97696cb..01b6bf0 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -401,7 +401,6 @@ const char *gprs_rlcmac_tbf::tbf_state_name[] = { "NULL", "ASSIGN", - "WAIT ASSIGN", "FLOW", "FINISHED", "WAIT RELEASE", @@ -820,12 +819,6 @@ if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { if (state_is(GPRS_RLCMAC_ASSIGN)) { LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " - "PACCH assignment timeout (not yet sent).\n", - tbf_name(this)); - tbf_free(this); - return; - } else if (state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { - LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " "PACCH assignment timeout.\n", tbf_name(this)); tbf_free(this); return; @@ -836,7 +829,7 @@ if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); dl_tbf->m_wait_confirm = 0; - if (dl_tbf->state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { + if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) { tbf_assign_control_ts(dl_tbf); if (!dl_tbf->upgrade_to_multislot) { @@ -997,8 +990,6 @@ if (poll_ass_dl) { set_polling(new_poll_fn, ts); - if (new_dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) - new_dl_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled DL Assignment polling on FN=%d, TS=%d\n", @@ -1071,8 +1062,6 @@ set_polling(new_poll_fn, ts); ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; - if (new_tbf->state_is(GPRS_RLCMAC_ASSIGN)) - new_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled UL Assignment polling on FN=%d, TS=%d\n", name(), poll_fn, poll_ts); diff --git a/src/tbf.h b/src/tbf.h index 3a6f42d..029af8a 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -43,8 +43,7 @@ enum gprs_rlcmac_tbf_state { GPRS_RLCMAC_NULL = 0, /* new created TBF */ - GPRS_RLCMAC_ASSIGN, /* wait for DL transmission */ - GPRS_RLCMAC_WAIT_ASSIGN,/* wait for confirmation */ + GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ @@ -231,7 +230,7 @@ int set_tlli_from_ul(uint32_t new_tlli); void merge_and_clear_ms(GprsMs *old_ms); - static const char *tbf_state_name[7]; + static const char *tbf_state_name[6]; class GprsMs *m_ms; @@ -316,7 +315,10 @@ { /* The TBF is established or has been assigned by a IMM.ASS for * download */ - return state > GPRS_RLCMAC_ASSIGN; + return state > GPRS_RLCMAC_ASSIGN || + (direction == GPRS_RLCMAC_DL_TBF && + state == GPRS_RLCMAC_ASSIGN && + (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))); } inline uint8_t gprs_rlcmac_tbf::tfi() const diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3e17d8f..c716a55 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1669,7 +1669,7 @@ ms2 = the_bts.ms_by_tlli(tlli1); OSMO_ASSERT(ms2 == ms1); OSMO_ASSERT(ms2->dl_tbf()); - OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_WAIT_ASSIGN)); + OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN)); dl_tbf2 = ms2->dl_tbf(); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0c9c877..8c6b78c 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -602,8 +602,7 @@ TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 08 00 03 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -629,8 +628,7 @@ TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 18 40 03 2b 2b 2b 2b -TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -656,8 +654,7 @@ TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 28 80 03 2b 2b 2b 2b -TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -683,8 +680,7 @@ TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 38 c0 03 2b 2b 2b 2b -TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -710,8 +706,7 @@ TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 49 00 03 2b 2b 2b 2b -TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -737,8 +732,7 @@ TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 59 40 03 2b 2b 2b 2b -TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -764,8 +758,7 @@ TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 69 80 03 2b 2b 2b 2b -TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -791,8 +784,7 @@ TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 79 c0 03 2b 2b 2b 2b -TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -818,8 +810,7 @@ TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 8a 00 03 2b 2b 2b 2b -TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -845,8 +836,7 @@ TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 9a 40 03 2b 2b 2b 2b -TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -872,8 +862,7 @@ TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 aa 80 03 2b 2b 2b 2b -TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -899,8 +888,7 @@ TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 ba c0 03 2b 2b 2b 2b -TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -926,8 +914,7 @@ TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 cb 00 03 2b 2b 2b 2b -TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -953,8 +940,7 @@ TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 db 40 03 2b 2b 2b 2b -TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -980,8 +966,7 @@ TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 eb 80 03 2b 2b 2b 2b -TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1007,8 +992,7 @@ TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 00 fb c0 03 2b 2b 2b 2b -TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1034,8 +1018,7 @@ TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 0c 00 03 2b 2b 2b 2b -TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1061,8 +1044,7 @@ TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 1c 40 03 2b 2b 2b 2b -TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1088,8 +1070,7 @@ TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 2c 80 03 2b 2b 2b 2b -TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1115,8 +1096,7 @@ TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 3c c0 03 2b 2b 2b 2b -TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1142,8 +1122,7 @@ TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 4d 00 03 2b 2b 2b 2b -TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1169,8 +1148,7 @@ TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 5d 40 03 2b 2b 2b 2b -TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1196,8 +1174,7 @@ TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 6d 80 03 2b 2b 2b 2b -TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1223,8 +1200,7 @@ TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 7d c0 03 2b 2b 2b 2b -TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1250,8 +1226,7 @@ TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 8e 00 03 2b 2b 2b 2b -TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1277,8 +1252,7 @@ TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 9e 40 03 2b 2b 2b 2b -TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1304,8 +1278,7 @@ TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ae 80 03 2b 2b 2b 2b -TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1331,8 +1304,7 @@ TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 be c0 03 2b 2b 2b 2b -TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1358,8 +1330,7 @@ TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 cf 00 03 2b 2b 2b 2b -TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1385,8 +1356,7 @@ TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 df 40 03 2b 2b 2b 2b -TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1412,8 +1382,7 @@ TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ef 80 03 2b 2b 2b 2b -TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1439,8 +1408,7 @@ TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 00 00 01 ff c0 03 2b 2b 2b 2b -TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1474,11 +1442,10 @@ TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=220 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 1c 00 dc 01 23 45 68 00 03 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append Modifying MS object, TLLI = 0xc0123456, TA 220 -> 0 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to RELEASING +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) free PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. Detaching TBF from MS object, TLLI = 0xc0123456, TBF = TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) @@ -1504,37 +1471,36 @@ TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==0) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) - Sending new block at BSN 0, CS=CS-1 -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) data block (BSN 0, CS-1): 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - need_padding 0 spb_status 0 spb 0(BSN1 0 BSN2 -1) - Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==1) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) data block (BSN 1, CS-1): 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 - need_padding 0 spb_status 0 spb 0(BSN1 1 BSN2 -1) - Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==2) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- Final block, so we done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FINISHED +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FINISHED data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 - need_padding 0 spb_status 0 spb 0(BSN1 2 BSN2 -1) - Copying data unit 0 (BSN 2) @@ -1569,26 +1535,29 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b 29 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) changes state from FLOW to WAIT ASSIGN Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) restarting timer 3169 while old timer 3169 pending -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) -- Frame 1 starts at offset 4, length=16, is_complete=1 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) complete UL frame len=16 -LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) len=16 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) complete UL frame len=16 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) len=16 No bctx +- No gaps in received block, last block: BSN=0 CV=0 +- Finished with UL TBF +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED - Scheduling Ack/Nack, because TLLI is included. -Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN)', TA=7 +- Scheduling Ack/Nack, because last block has CV==0. +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FINISHED)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=0/0 @@ -1613,8 +1582,7 @@ TX: START TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=7 TA=7 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=33 34 34 2d 06 3f 30 0f 00 00 7d 80 00 07 00 df 12 23 34 48 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) append Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b MS requests UL TBF on RACH, so we provide one: MS requests single block allocation @@ -1654,16 +1622,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -1740,16 +1707,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -1792,7 +1758,6 @@ +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1801,7 +1766,7 @@ ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Packet Control Ack TBF: [UPLINK] DOWNLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -1881,16 +1846,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654348 TS 7 -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 -Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 +Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=48 28 5e ac ce f1 0f 1d 00 00 88 40 09 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=1, CPS=0, RSB=0, rc=184 @@ -1953,16 +1917,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2050,16 +2013,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654340 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=1/0 Slot Allocation (Algorithm A) for class 1 @@ -2132,16 +2094,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2214,15 +2175,14 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b ed 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) changes state from FLOW to WAIT ASSIGN Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) restarting timer 3169 while old timer 3169 pending -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Got RACH from TLLI=0x00000000 while TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) still exists. Killing pending DL TBF TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING @@ -2240,10 +2200,14 @@ - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) -- Frame 1 starts at offset 4, length=16, is_complete=1 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) complete UL frame len=16 -LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) len=16 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) complete UL frame len=16 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) len=16 No bctx +- No gaps in received block, last block: BSN=0 CV=0 +- Finished with UL TBF +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED - Scheduling Ack/Nack, because TLLI is included. +- Scheduling Ack/Nack, because last block has CV==0. New MS: TLLI = 0xf1223344, TA = 7, IMSI = 0011223344, LLC = 2 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b MS requests UL TBF on RACH, so we provide one: @@ -2284,16 +2248,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2375,7 +2338,6 @@ +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2384,7 +2346,7 @@ ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Packet Control Ack TBF: [UPLINK] DOWNLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -3063,7 +3025,6 @@ +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE): Scheduling polling at FN 2654413 TS 7 -TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Scheduled DL Assignment polling on FN=2654413, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654400 block=2 data=48 08 20 08 0c 72 00 02 18 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -3078,7 +3039,7 @@ PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING), 1 TBFs, USFs = 01, TFIs = 00000002. Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) ********** TBF ends here ********** -TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW +TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -3425,16 +3386,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -3518,16 +3478,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -6281,16 +6240,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -6454,16 +6412,15 @@ +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f8 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to FLOW Got RLC block, coding scheme: MCS-4, length: 49 (49)) UL data: 1d 00 40 c1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got MCS-4 RLC block: R=1, SI=0, TFI=0, CPS=5, RSB=0, rc=385 -- To view, visit https://gerrit.osmocom.org/218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I1532f8e93194368cdc1e3846f82afa6d68cd5fbd Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 16 05:54:16 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 05:54:16 +0000 Subject: [MERGED] osmo-pcu[master]: Handle EGPRS 11 bit RACH in osmo-pcu In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: Handle EGPRS 11 bit RACH in osmo-pcu ...................................................................... Handle EGPRS 11 bit RACH in osmo-pcu A function is_single_block is added to get request type of RACH. EGPRS 11 bit RACH is handled. Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 --- M src/bts.cpp M src/bts.h 2 files changed, 84 insertions(+), 11 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/bts.cpp b/src/bts.cpp index 795baa6..015bf9f 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -480,20 +480,16 @@ uint8_t usf = 7; uint8_t tsc; uint16_t ta; + uint16_t ms_class = 0; + uint16_t priority = 0; rach_frame(); LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + if (qta < 0) qta = 0; if (qta > 252) @@ -516,8 +512,16 @@ } else { // Create new TBF #warning "Copy and paste with other routines.." - /* set class to 0, since we don't know the multislot class yet */ - tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + + if (is_11bit) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0, since we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + if (!tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); /* FIXME: send reject */ @@ -565,6 +569,73 @@ return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (!val) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase " + "access but we force two phase " + "access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index 801342d..ba6fc4d 100644 --- a/src/bts.h +++ b/src/bts.h @@ -290,6 +290,8 @@ int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst_type); -- To view, visit https://gerrit.osmocom.org/430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I61d74a32f7764644ed86f7fdf97fa3c2f61503f7 Gerrit-PatchSet: 10 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Fri Sep 16 06:00:56 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 06:00:56 +0000 Subject: [MERGED] osmo-pcu[master]: Update the function immediate assignment for EGPRS In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: Update the function immediate assignment for EGPRS ...................................................................... Update the function immediate assignment for EGPRS Encode the EGPRS fields of immediate assignment message in uplink when EGPRS PACKET CHANNEL REQUEST (11 bit RACH) is received. The series of patches for 11 bit RACH are dependent on libosmocore and osmo-bts patches for 11 bit RACH. Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 --- M src/bts.cpp M src/encoding.cpp M src/encoding.h 3 files changed, 85 insertions(+), 12 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/bts.cpp b/src/bts.cpp index 015bf9f..73ec1f7 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -556,7 +556,7 @@ plen = Encoding::write_immediate_assignment( tbf, immediate_assignment, 0, ra, Fn, ta, m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, - m_bts.alpha, m_bts.gamma, -1); + m_bts.alpha, m_bts.gamma, -1, burst_type, sb); if (plen >= 0) { pcu_l1if_tx_agch(immediate_assignment, plen); diff --git a/src/encoding.cpp b/src/encoding.cpp index 41e0d10..7d3fa14 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -147,11 +147,71 @@ gprs_rlcmac_ul_tbf *tbf, bitvec * dest, unsigned& wp, uint8_t usf, uint32_t fn, - uint8_t alpha, uint8_t gamma, int8_t ta_idx) + uint8_t alpha, uint8_t gamma, int8_t ta_idx, + enum ph_burst_type burst_type, uint16_t ra) { - LOGP(DRLCMACUL, LOGL_ERROR, - "EGPRS Packet Uplink Assignment is not yet implemented\n"); - return -EINVAL; + unsigned int ws_enc = 0; + uint8_t extended_ra = 0; + + extended_ra = (ra & 0x1F); + + bitvec_write_field(dest, wp, 1, 2); /* LH */ + bitvec_write_field(dest, wp, 0, 2); /* 0 EGPRS Uplink Assignment */ + bitvec_write_field(dest, wp, extended_ra, 5); /* Extended RA */ + bitvec_write_field(dest, wp, 0, 1); /* Access technology Request */ + + if (tbf == NULL) { + + bitvec_write_field(dest, wp, 0, 1); /* multiblock allocation */ + + if (alpha) { + bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + } else { + bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + } + + bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, wp, (fn / (26 * 51)) % 32, 5);/* T1' */ + bitvec_write_field(dest, wp, fn % 51, 6); /* T3 */ + bitvec_write_field(dest, wp, fn % 26, 5); /* T2 */ + bitvec_write_field(dest, wp, 0, 2); /* Radio block allocation */ + + bitvec_write_field(dest, wp, 0, 1); + + } else { + + ws_enc = (tbf->m_window.ws() - 64) / 32; + + bitvec_write_field(dest, wp, 1, 1); /* single block alloc */ + bitvec_write_field(dest, wp, tbf->tfi(), 5);/* TFI assignment */ + bitvec_write_field(dest, wp, 0, 1); /* polling bit */ + bitvec_write_field(dest, wp, 0, 1); /* constant */ + bitvec_write_field(dest, wp, usf, 3); /* USF bit */ + bitvec_write_field(dest, wp, 0, 1); /* USF granularity */ + bitvec_write_field(dest, wp, 0, 1); /* P0 */ + /* MCS */ + bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 4); + /* tlli channel block */ + bitvec_write_field(dest, wp, tbf->tlli(), 1); + bitvec_write_field(dest, wp, 0, 1); /* BEP period present */ + bitvec_write_field(dest, wp, 0, 1); /* resegmentation */ + bitvec_write_field(dest, wp, ws_enc, 5);/* egprs window_size */ + + if (alpha) { + bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + } else { + bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + } + + bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, wp, 0, 1); /* TIMING_ADVANCE_INDEX */ + bitvec_write_field(dest, wp, 0, 1); /* TBF_STARTING_TIME_FLAG */ + bitvec_write_field(dest, wp, 0, 1); /* NULL */ + } + + return 0; } /* @@ -160,10 +220,10 @@ */ int Encoding::write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t usf, uint8_t polling, uint32_t fn, uint8_t alpha, - uint8_t gamma, int8_t ta_idx) + uint8_t gamma, int8_t ta_idx, enum ph_burst_type burst_type, uint8_t sb) { unsigned wp = 0; int plen; @@ -189,7 +249,13 @@ bitvec_write_field(dest, wp,arfcn,10); // ARFCN //10.5.2.30 Request Reference - bitvec_write_field(dest, wp,ra,8); // RA + if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + bitvec_write_field(dest, wp, 0x7f, 8); /* RACH value */ + } else { + bitvec_write_field(dest, wp, ra, 8); /* RACH value */ + } + bitvec_write_field(dest, wp,(ref_fn / (26 * 51)) % 32,5); // T1' bitvec_write_field(dest, wp,ref_fn % 51,6); // T3 bitvec_write_field(dest, wp,ref_fn % 26,5); // T2 @@ -213,10 +279,11 @@ rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp, polling, gsm48_ta_is_valid(ta), fn, alpha, gamma, ta_idx); - else if (as_ul_tbf(tbf) && as_ul_tbf(tbf)->is_egprs_enabled()) + else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) rc = write_ia_rest_egprs_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, - alpha, gamma, ta_idx); + alpha, gamma, ta_idx, burst_type, ra); else rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, diff --git a/src/encoding.h b/src/encoding.h index 710de78..69f8cdc 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -23,6 +23,9 @@ #include #include #include +extern "C" { +#include +} struct gprs_rlcmac_bts; struct gprs_rlcmac_tbf; @@ -40,11 +43,14 @@ public: static int write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t usf, uint8_t polling, uint32_t fn, uint8_t alpha, uint8_t gamma, - int8_t ta_idx); + int8_t ta_idx, + enum ph_burst_type burst_type = + GSM_L1_BURST_TYPE_ACCESS_0, + uint8_t sb = 1); static void write_packet_uplink_assignment( struct gprs_rlcmac_bts *bts, -- To view, visit https://gerrit.osmocom.org/431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie5e309156e5dbbb6add74a1b4d257c4ee2332e52 Gerrit-PatchSet: 8 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Fri Sep 16 06:01:14 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 06:01:14 +0000 Subject: [MERGED] osmo-bts[master]: Update parameters in osmo-bts-sysmo for 11bit RACH In-Reply-To: References: Message-ID: arvind.sirsikar has submitted this change and it was merged. Change subject: Update parameters in osmo-bts-sysmo for 11bit RACH ...................................................................... Update parameters in osmo-bts-sysmo for 11bit RACH Based on the indication from L1, number of bits in RACH and burst type is determined. Appropriate parameters are filled in osmo-bts-sysmo These parameters are sent to osmo-pcu for processing of the RACH. Change-Id: I93831ddfb3f31b637e6a576f23a9bb4557758582 --- M src/osmo-bts-sysmo/l1_if.c 1 file changed, 36 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..40ac12d 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -929,7 +929,8 @@ struct gsm_lchan *lchan; struct osmo_phsap_prim *l1sap; uint32_t fn; - uint8_t ra, acc_delay = 0; + uint8_t acc_delay = 0; + uint16_t ra = 0, is_11bit = 0, burst_type = 0, temp = 0; int rc; /* increment number of busy RACH slots, if required */ @@ -951,16 +952,28 @@ btsb->load.rach.access++; dump_meas_res(LOGL_DEBUG, &ra_ind->measParam); + burst_type = ra_ind->burstType; - if (ra_ind->msgUnitParam.u8Size != 1) { + if ((ra_ind->msgUnitParam.u8Size != 1) && + (ra_ind->msgUnitParam.u8Size != 2)) { LOGP(DL1C, LOGL_ERROR, "PH-RACH-INDICATION has %d bits\n", ra_ind->sapi); msgb_free(l1p_msg); return 0; } + if (ra_ind->msgUnitParam.u8Size == 2) { + is_11bit = 1; + ra = ra_ind->msgUnitParam.u8Buffer[0]; + ra = ra << 3; + temp = (ra_ind->msgUnitParam.u8Buffer[1] & 0x7); + ra = ra | temp; + } else { + is_11bit = 0; + ra = ra_ind->msgUnitParam.u8Buffer[0]; + } + fn = ra_ind->u32Fn; - ra = ra_ind->msgUnitParam.u8Buffer[0]; rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive data\n"); @@ -970,11 +983,28 @@ l1sap->u.rach_ind.ra = ra; l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; + l1sap->u.rach_ind.is_11bit = is_11bit; /* no of bits in 11 bit RACH */ - /* Initialising the parameters needs to be handled when 11 bit RACH */ + /*mapping of the burst type, the values are specific to osmo-bts-sysmo*/ - l1sap->u.rach_ind.is_11bit = 0; - l1sap->u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_0; + switch (burst_type) { + case GsmL1_BurstType_Access_0: + l1sap->u.rach_ind.burst_type = + GSM_L1_BURST_TYPE_ACCESS_0; + break; + case GsmL1_BurstType_Access_1: + l1sap->u.rach_ind.burst_type = + GSM_L1_BURST_TYPE_ACCESS_1; + break; + case GsmL1_BurstType_Access_2: + l1sap->u.rach_ind.burst_type = + GSM_L1_BURST_TYPE_ACCESS_2; + break; + default: + l1sap->u.rach_ind.burst_type = + GSM_L1_BURST_TYPE_NONE; + break; + } if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) -- To view, visit https://gerrit.osmocom.org/434 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I93831ddfb3f31b637e6a576f23a9bb4557758582 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: bhargava_abhyankar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: bhargava_abhyankar From gerrit-no-reply at lists.osmocom.org Fri Sep 16 08:14:00 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 08:14:00 +0000 Subject: osmo-pcu[master]: Handle Timing Advance IE properly In-Reply-To: References: Message-ID: Patch Set 6: The reason is that bitvec_write_field() requires it that way - see the definition in src/bitvector.h:47. We can call it from libosmocore directly instead of using wrapper but as bitvec_write_field wrapper is used extensively in this file already this would add unnecessary confusion - I think it would be better to convert it in 1 go in separate config. -- To view, visit https://gerrit.osmocom.org/552 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I786bf7fc999d401cc3d9e7f1e7a1fba953b5d458 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 09:25:29 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 09:25:29 +0000 Subject: [PATCH] osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/819 to look at the new patch set (#2). Fix slot allocation based on direction configured Currently number of TS for second DL TBF is less compared to first DL TBF because PCU is considering the combined capacity. With this issue there was no fairness in throughput between the 2 DL TBFs This patch enables the user to control the number of TS allocation for the DL/UL TBF based on the direction configured through VTY with cfg_pcu_ts_alloc_maximise_cmd Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.cpp M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 7 files changed, 43 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/2 diff --git a/src/bts.cpp b/src/bts.cpp index 73ec1f7..12eb81e 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -694,7 +694,6 @@ bitvec_free(immediate_assignment); } - GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; diff --git a/src/bts.h b/src/bts.h index ba6fc4d..59e614f 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,11 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum maximise_direction { + DL_ONLY, + UL_ONLY, + DL_UL_BOTH +}; struct BTS; struct GprsMs; @@ -191,6 +196,8 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + enum maximise_direction max_ts_direction_cfgd; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..dc908b5 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -775,8 +775,13 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) + if (bts->max_ts_direction_cfgd == UL_ONLY) { + if (tx_window < max_ul_slots) + continue; + } else if (bts->max_ts_direction_cfgd == DL_ONLY) { + if (rx_window < max_dl_slots) + continue; + } else if (capacity <= max_capacity) continue; max_capacity = capacity; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..fbb16bc 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->max_ts_direction_cfgd = DL_UL_BOTH; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..1ffbefc 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,23 @@ return CMD_SUCCESS; } +DEFUN(cfg_pcu_ts_alloc_maximise_type, + cfg_pcu_ts_alloc_maximise_cmd, + "maximise-direction (dl|ul)", + "number of TS allocation based on direction configured\n" + "maximise DL capacity\n" + "maximise UL capacity") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + if (!strcmp(argv[0], "dl")) + bts->max_ts_direction_cfgd = DL_ONLY; + else if (!strcmp(argv[0], "ul")) + bts->max_ts_direction_cfgd = UL_ONLY; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +989,7 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_ts_alloc_maximise_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index f7794f7..44c01e6 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->max_ts_direction_cfgd = DL_UL_BOTH; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -238,6 +240,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -285,6 +288,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[1].enable(); @@ -660,6 +664,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +703,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +812,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_ONLY; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -830,13 +837,8 @@ if (dl_tbf2->pdch[i]) numTs2++; } - - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 == 4); tbf_free(dl_tbf1); tbf_free(dl_tbf2); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..9717411 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10795,4 +10795,4 @@ Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs TBF1: numTs(4) -TBF2: numTs(3) +TBF2: numTs(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 09:27:01 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Fri, 16 Sep 2016 09:27:01 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: I have addressed all the comments raised. please let me know the status. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 09:46:39 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 16 Sep 2016 09:46:39 +0000 Subject: osmo-pcu[master]: Handle Timing Advance IE properly In-Reply-To: References: Message-ID: Patch Set 6: -Code-Review -- To view, visit https://gerrit.osmocom.org/552 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I786bf7fc999d401cc3d9e7f1e7a1fba953b5d458 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 11:03:01 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 11:03:01 +0000 Subject: libosmocore[master]: Add function to send TRAP over Control Interface In-Reply-To: References: Message-ID: Patch Set 2: Could you send constify patch for libosmocore to gerrit? -- To view, visit https://gerrit.osmocom.org/649 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic0b8d88c4f5c4d42c3f8fb754f8eabf049c9e388 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 11:18:44 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 11:18:44 +0000 Subject: osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/819/2/src/bts.cpp File src/bts.cpp: Line 696: fix this -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 16 11:26:13 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 16 Sep 2016 11:26:13 +0000 Subject: [PATCH] osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/819 to look at the new patch set (#3). Fix slot allocation based on direction configured Currently number of TS for second DL TBF is less compared to first DL TBF because PCU is considering the combined capacity during TS allocation. With this issue there was no fairness in throughput between the 2 DL TBFs This patch enables the user to maximize the number of TS allocation for the DL or UL TBF based on the direction configured through VTY with cfg_pcu_ts_alloc_maximise_cmd Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 6 files changed, 43 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/3 diff --git a/src/bts.h b/src/bts.h index ba6fc4d..59e614f 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,11 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum maximise_direction { + DL_ONLY, + UL_ONLY, + DL_UL_BOTH +}; struct BTS; struct GprsMs; @@ -191,6 +196,8 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + enum maximise_direction max_ts_direction_cfgd; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..dc908b5 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -775,8 +775,13 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) + if (bts->max_ts_direction_cfgd == UL_ONLY) { + if (tx_window < max_ul_slots) + continue; + } else if (bts->max_ts_direction_cfgd == DL_ONLY) { + if (rx_window < max_dl_slots) + continue; + } else if (capacity <= max_capacity) continue; max_capacity = capacity; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..fbb16bc 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->max_ts_direction_cfgd = DL_UL_BOTH; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..1ffbefc 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,23 @@ return CMD_SUCCESS; } +DEFUN(cfg_pcu_ts_alloc_maximise_type, + cfg_pcu_ts_alloc_maximise_cmd, + "maximise-direction (dl|ul)", + "number of TS allocation based on direction configured\n" + "maximise DL capacity\n" + "maximise UL capacity") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + if (!strcmp(argv[0], "dl")) + bts->max_ts_direction_cfgd = DL_ONLY; + else if (!strcmp(argv[0], "ul")) + bts->max_ts_direction_cfgd = UL_ONLY; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +989,7 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_ts_alloc_maximise_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index f7794f7..44c01e6 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->max_ts_direction_cfgd = DL_UL_BOTH; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -238,6 +240,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -285,6 +288,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[1].enable(); @@ -660,6 +664,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +703,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->max_ts_direction_cfgd = DL_UL_BOTH; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +812,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->max_ts_direction_cfgd = DL_ONLY; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -830,13 +837,8 @@ if (dl_tbf2->pdch[i]) numTs2++; } - - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 == 4); tbf_free(dl_tbf1); tbf_free(dl_tbf2); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..9717411 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10795,4 +10795,4 @@ Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs TBF1: numTs(4) -TBF2: numTs(3) +TBF2: numTs(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:27:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:27:20 +0000 Subject: openbsc[master]: DTX: store time instead of fn In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 this is IMHO the completely wrong way. The only relevant time base to anything in the GSM PHY is the TDMA time clock based on the frame number. Anything else is irrelevant. Yes, GSM voice frames are sampled from a real-time clock every 20ms. Yes, the SID (in the BTS->PHY->Um->MS direction) needs to be sent nominally every 160ms. But no, it is not _exactly_ 160ms, but it is of course at the time when the respective (8th) PH-RTS.req of the PHY is happening, which correpsonds to more or less 160ms later. Due to the multiframe scheduling of the 26-multiframe, it is not always _exactly_ 160ms wall-clock time, but has some jitter. On average, it is 160ms. In the MS->Um->PHY->BTS->RTP direction, it is similar. The MS will (have to) send a SID every 8 codec frames, which is on average 160ms, but not _exactly_. It is every 8 codec frames, as defined by the GSM multiframe structure. Yes, that means that we will not neccessarily send a RTP SID every 160ms wall clock time. But it is the same as with the regular voice-carrying codec frames. nominally they appear every 20ms, and they contain RTP timestamps incrementing in 20ms intervals. But the exact time the RTP is sent is not 20ms according to wall-clock time, but whenever the PHY reports a codec frame via PH-DATA.ind. -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:28:32 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 13:28:32 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#4). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 8 files changed, 73 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/4 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..37afc92 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Remove RTP header Marker bit */ + marker = msgb_get_u8(resp_msg); + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Add RTP header Marker bit */ + msgb_put_u8(msg, marker); /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..a7f0475 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ @@ -500,7 +500,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..7dd4f95 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -88,7 +90,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..7ee503a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -288,6 +291,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -297,7 +301,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; uint8_t *l1_payload; @@ -327,9 +331,22 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + uint8_t cmr; + int8_t sti, cmi; + + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..26b1819 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ @@ -493,6 +493,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..47720d5 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -108,7 +110,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..fa262c2 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -385,6 +388,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -394,7 +398,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; uint8_t *l1_payload; @@ -426,9 +430,22 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + uint8_t cmr; + int8_t sti, cmi; + + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:31:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:31:00 +0000 Subject: openbsc[master]: bsc: count the usage of codec by setting the lchan active In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (1 comment) please address the cosmetic issue, otherwise it's +2. thanks! https://gerrit.osmocom.org/#/c/794/2/openbsc/src/libbsc/abis_rsl.c File openbsc/src/libbsc/abis_rsl.c: Line 89: case GSM48_CMODE_SPEECH_AMR: kernel coding style commonly doesn't have an extra indent for the 'case' within a 'switch'. -- To view, visit https://gerrit.osmocom.org/794 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifc8a406a11dce16b9e7f3310841e470545550a2c Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:34:48 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:34:48 +0000 Subject: openbsc[master]: msc: add counters to track call attempts/active/success/failed In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (2 comments) please use more conscise wording to avoid misunderstandings. https://gerrit.osmocom.org/#/c/795/1/openbsc/include/openbsc/gsm_data.h File openbsc/include/openbsc/gsm_data.h: Line 235: "base station controller", please use "[count] total amount of calls that ever reached active state" to make it clear that it is not about the currently concurrently active calls. https://gerrit.osmocom.org/#/c/795/2/openbsc/include/openbsc/gsm_data.h File openbsc/include/openbsc/gsm_data.h: Line 227: [MSC_CTR_CALL_ACTIVE] = {"call.active", "Count amount of calls reached state active."}, please use "[count] total amount of calls that ever reached active state" to make it clear that it is not about the currently concurrently active calls. -- To view, visit https://gerrit.osmocom.org/795 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I49b93af2e6a0ba16c2fb00b7b83974e8a6a16df3 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:37:22 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:37:22 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 4: I'm sorry, but what exactly is the point of this? It's not a polemical question, but is there a practical benefit? I'm not aware of any explicit or implicit automake coding style rules. Please explain :) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:37:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:37:52 +0000 Subject: openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:38:17 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:38:17 +0000 Subject: openbsc[master]: remove unused bsc_copyright from bsc_vty.c In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/851 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I281791c0f57ca75ffe14431a3030811b2d224f0b Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:42:59 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:42:59 +0000 Subject: openbsc[master]: Sanity fixes for gsm0408_dispatch(): rc, assertions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 will you also submit patches that actually use the result codes? I maan, it is nice for the RSL code in OsmoNITB/OsmoBSC to know that 04.08 couldn't be processed, but what about the MS? I guess the MS should be notified somehow that a given protocol descriptor didn't exist? -- To view, visit https://gerrit.osmocom.org/855 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:49:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:49:39 +0000 Subject: openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (3 comments) i'm sorry for my negative comments, but I'm not sure it is worth spending time on such patches... https://gerrit.osmocom.org/#/c/854/1/openbsc/include/openbsc/gsm_data.h File openbsc/include/openbsc/gsm_data.h: Line 106: /* mobile subscriber data */ you change from one no longer correct comment to another one that is misleading? The subscriber_conection represents only the persistent state we keep during an active radio connection of the subscriber. sure, it is subscriber data, but it is not to be confused with struct gsm_subscriber, right? https://gerrit.osmocom.org/#/c/854/1/openbsc/include/openbsc/gsm_data_shared.h File openbsc/include/openbsc/gsm_data_shared.h: Line 384: /* One TRX (transceiver) in a BTS */ seriously? I think if you start expanding all acronyms everywhere, you'd have a lot of time to do. Somebody who works on BTS or BSC source code and doesn't know what a TRX is, is probably looking at the wrong codebase anyway. https://gerrit.osmocom.org/#/c/854/1/openbsc/src/libmsc/gsm_04_08.c File openbsc/src/libmsc/gsm_04_08.c: Line 3660: /* Main entry point for receiving data from the BSC|RNC level. */ If you touch it anyway: Layer3 data? GSM 04.08/44.008 Layer 3 data? -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:52:40 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:52:40 +0000 Subject: openbsc[master]: debug log for sms: fix/add In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/856/1/openbsc/src/libmsc/gsm_04_11.c File openbsc/src/libmsc/gsm_04_11.c: Line 881: and what about the next rename? The proper way would be to use __FUNCTION__ or __func__ or whatever gcc guarantees as a stable name of the current function. We could also make it a compile-time option to include this in DEBUGP/LOGP, rather than only (or instead of?) file name and line number. -- To view, visit https://gerrit.osmocom.org/856 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:53:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:53:16 +0000 Subject: openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 13:54:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 16 Sep 2016 13:54:58 +0000 Subject: libosmocore[master]: utils/conv_gen.py: improve output formatting In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/829 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 14:09:49 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 14:09:49 +0000 Subject: [ABANDON] openbsc[master]: DTX: store time instead of fn In-Reply-To: References: Message-ID: Max has abandoned this change. Change subject: DTX: store time instead of fn ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/846 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ia46836d20357b3cfb3ad94596f1c28e3159fe394 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 16:59:50 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 16:59:50 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix last SID saving In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/845 to look at the new patch set (#4). DTX: fix last SID saving Previously SID was saved explicitly by each BTS model (lc15, sysmo) instead of relying on generic function. Fix it by using generic function and propagating necessary parameters for it. Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Fixes: OS#1800 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 14 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/845/4 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..da63e00 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..41d6989 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -88,7 +88,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..5badc4d 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,7 +200,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -270,14 +270,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } @@ -297,7 +291,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; uint8_t *l1_payload; @@ -329,7 +323,7 @@ case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + rtp_pl_len, lchan, fn); break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..7280c1d 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..bd694ec 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -108,7 +108,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..6c78ceb 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,7 +283,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -367,14 +367,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } @@ -394,7 +388,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; uint8_t *l1_payload; @@ -428,7 +422,7 @@ case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + rtp_pl_len, lchan, fn); break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 16 16:59:51 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 16:59:51 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix SID repeat scheduling Message-ID: Review at https://gerrit.osmocom.org/857 DTX: fix SID repeat scheduling Previously SID retransmission was scheduled incorrectly based on GSM frames instead of voice frames. Fix this by using GSM Fn only as elapsed time estimation: * move saved SID retransmission into generic function from lc15 and sysmo specific code * split retransmission time check into separate generic function * compute estimation for elapsed time since last retransmission using GSM Fn Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Fixes: OS#1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 67 insertions(+), 116 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/57/857/1 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..9e39c08 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -23,6 +23,9 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, uint32_t fn, bool update); +uint8_t repeat_last_sid(const struct gsm_lchan *lchan, uint8_t *dst, + uint32_t fn); +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..a72a1b6 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -111,6 +112,49 @@ memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type) or 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(const struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + return 0; +} + +/*! \brief Check if enough time has passed since last SID (if any) to repeat it + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +{ + /* Compute approx. time delta based on Fn duration */ + uint32_t delta = (fn - lchan->tch.last_sid.fn) * 120 / 26; + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 8) + return true; + return false; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 3) + return true; + return false; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5badc4d..4fdf6a6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -463,27 +463,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -506,30 +485,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -541,14 +503,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -556,14 +513,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 6c78ceb..ee72e53 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -566,27 +566,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -609,30 +588,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -644,14 +606,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -659,14 +616,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/857 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 16 17:08:40 2016 From: gerrit-no-reply at lists.osmocom.org (ahuemer) Date: Fri, 16 Sep 2016 17:08:40 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 4: As Neels mentioned it is mostly just bikeshedding. I initially submitted an equivalent patch to [2] (it was [1]) that was rejected because I fixed some whitespace inconsistencies in the same patch. So I did split that up in two patches according to Neels suggestion and made all Makefile.am files in the repository consistent in whitespace usage and line breaks. Since I had to decide on a formatting rule I came up with the content of this patch because I think it is very straight forward, although maybe a bit demanding in vertical screen space. [1] https://gerrit.osmocom.org/824 [2] https://gerrit.osmocom.org/839 -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: ahuemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: ahuemer Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 16 17:09:11 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 17:09:11 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix SID repeat scheduling In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/857 to look at the new patch set (#2). DTX: fix SID repeat scheduling Previously SID retransmission was scheduled incorrectly based on GSM frames instead of voice frames. Fix this by using GSM Fn only as elapsed time estimation: * move saved SID retransmission into generic function from lc15 and sysmo specific code * split retransmission time check into separate generic function * compute estimation for elapsed time since last retransmission using GSM Fn Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Fixes: OS#1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 66 insertions(+), 116 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/57/857/2 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..cde7a93 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -23,6 +23,8 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, uint32_t fn, bool update); +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..61d2dea 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -111,6 +112,49 @@ memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type) or 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + return 0; +} + +/*! \brief Check if enough time has passed since last SID (if any) to repeat it + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +{ + /* Compute approx. time delta based on Fn duration */ + uint32_t delta = (fn - lchan->tch.last_sid.fn) * 120 / 26; + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 8) + return true; + return false; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 3) + return true; + return false; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5badc4d..4fdf6a6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -463,27 +463,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -506,30 +485,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -541,14 +503,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -556,14 +513,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 6c78ceb..ee72e53 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -566,27 +566,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -609,30 +588,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -644,14 +606,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -659,14 +616,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/857 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 16 17:51:53 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 17:51:53 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix SID logic Message-ID: Review at https://gerrit.osmocom.org/858 DTX: fix SID logic Previously receiving SID via RTP always caused it's transmission to L1 regardless of the time which might have resulted in excess traffic. Fix this by only saving SID data and transmitting it later on as necessary according to 3GPP TS 26.093 A.5.1.1. Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Fixes: OS#1801 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/tch.c 4 files changed, 24 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/58/858/1 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index da63e00..4c5a535 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -466,10 +466,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn) < 0) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 4fdf6a6..0daacf9 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -270,8 +270,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -324,6 +326,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return rc; break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 7280c1d..cb7f9a5 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -459,10 +459,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn) < 0) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index ee72e53..4c1a3f7 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -367,8 +367,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -423,6 +425,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return rc; break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/858 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 16 18:03:22 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 16 Sep 2016 18:03:22 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix SID logic In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/858 to look at the new patch set (#2). DTX: fix SID logic Previously receiving SID via RTP always caused it's transmission to L1 regardless of the time which might have resulted in excess traffic. Fix this by only saving SID data and transmitting it later on as necessary according to 3GPP TS 26.093 A.5.1.1. Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Fixes: OS#1801 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 38 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/58/858/2 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index da63e00..21d047a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -466,10 +466,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (!l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn)) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 41d6989..f01fdc2 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -87,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 4fdf6a6..6ac2763 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -270,8 +270,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -279,9 +281,9 @@ #define RTP_MSGB_ALLOC_SIZE 512 /*! \brief function for incoming RTP via TCH.req - * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -290,7 +292,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; @@ -324,6 +326,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; break; default: /* we don't support CSD modes */ @@ -334,13 +338,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return; + return false; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); + return true; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 7280c1d..0bc6d14 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -459,10 +459,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (!l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn)) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index bd694ec..49b7e67 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -107,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index ee72e53..4ea95c5 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -367,8 +367,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -376,9 +378,9 @@ #define RTP_MSGB_ALLOC_SIZE 512 /*! \brief function for incoming RTP via TCH.req - * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -387,7 +389,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; @@ -423,6 +425,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; break; default: /* we don't support CSD modes */ @@ -433,13 +437,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return; + return false; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); + return true; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/858 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 01:59:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 01:59:18 +0000 Subject: openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Patch Set 1: Yes... this is pretty old cruft from when I was just starting on IuCS, cosmetic changes combed out of the rest. About TRX, I was indeed wondering what it meant back then. And there is admittedly some ambiguity, with osmo-trx and osmo-bts-trx around, where 'trx' rather means 'usrp'. It's slightly painful to keep stupid comments around, but we can just drop this. -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 02:26:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 02:26:38 +0000 Subject: openbsc[master]: Sanity fixes for gsm0408_dispatch(): rc, assertions In-Reply-To: References: Message-ID: Patch Set 1: I wasn't thinking that far. Fixed the coverity issue and saw that two failure paths returned rc = 0. There are several callers of gsm0408_dispatch(), none of which actually care about the rc. IuCS will add a caller that takes the rc all the way back to the IuCS rx callback ... and then ignores it. I guess letting the MS/UE know about failures like these is a whole new thing to get involved in, so I'd "postpone" it: https://osmocom.org/issues/1812 -- To view, visit https://gerrit.osmocom.org/855 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 02:27:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 02:27:20 +0000 Subject: openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Patch Set 1: well, ok, did not drop it entirely... -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 02:38:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 02:38:20 +0000 Subject: [PATCH] openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/854 to look at the new patch set (#2). cosmetic: various comment, whitespace tweaks Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c M openbsc/src/libmsc/gsm_04_08.c M openbsc/tests/bsc/bsc_test.c 4 files changed, 4 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/54/854/2 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..f7c0d47 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -103,7 +103,7 @@ uint8_t last_seen_nr; }; -/* the per subscriber data for lchan */ +/* active radio connection of a mobile subscriber */ struct gsm_subscriber_connection { struct llist_head entry; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index b8b5967..8c830a3 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -247,7 +247,6 @@ if (!conn) return NULL; - /* Configure the time and start it so it will be closed */ conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c30fbb0..76217ae 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1088,7 +1088,7 @@ if (subscr) { subscr_update(subscr, bts, - GSM_SUBSCRIBER_UPDATE_DETACHED); + GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr)); subscr->equipment.classmark1 = idi->classmark1; @@ -3657,7 +3657,7 @@ return 0; } -/* here we get data from the BSC level... */ +/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); diff --git a/openbsc/tests/bsc/bsc_test.c b/openbsc/tests/bsc/bsc_test.c index d032f61..cc45652 100644 --- a/openbsc/tests/bsc/bsc_test.c +++ b/openbsc/tests/bsc/bsc_test.c @@ -139,7 +139,7 @@ conn->bts = bts; conn->sccp_con = sccp_con; - /* start testinh with proper messages */ + /* start testing with proper messages */ printf("Testing BTS<->MSC message scan.\n"); for (i = 0; i < ARRAY_SIZE(test_scan_defs); ++i) { const struct test_definition *test_def = &test_scan_defs[i]; -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 17 02:38:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 02:38:20 +0000 Subject: [PATCH] openbsc[master]: debug log for sms: fix/add In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/856 to look at the new patch set (#2). debug log for sms: fix/add One logged the wrong function name. Add others. Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 --- M openbsc/src/libmsc/gsm_04_11.c M openbsc/src/libmsc/sms_queue.c M openbsc/src/libmsc/vty_interface_layer3.c 3 files changed, 14 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/56/856/2 diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 6d3f41b..c038882 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -879,7 +879,7 @@ return -EBUSY; } - DEBUGP(DLSMS, "send_sms_lchan()\n"); + DEBUGP(DLSMS, "%s()\n", __func__); /* FIXME: allocate transaction with message reference */ trans = trans_alloc(conn->bts->network, conn->subscr, @@ -987,10 +987,14 @@ * if yes, send the SMS this way */ conn = connection_for_subscr(subscr); if (conn) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS via already open connection %p to %s\n", + conn, subscr_name(subscr)); return gsm411_send_sms(conn, sms); } /* if not, we have to start paging */ + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n", + subscr_name(subscr)); res = subscr_request_channel(subscr, RSL_CHANNEED_SDCCH, paging_cb_send_sms, sms); if (!res) { diff --git a/openbsc/src/libmsc/sms_queue.c b/openbsc/src/libmsc/sms_queue.c index 5dbe81f..ebc53c2 100644 --- a/openbsc/src/libmsc/sms_queue.c +++ b/openbsc/src/libmsc/sms_queue.c @@ -225,10 +225,14 @@ sms = take_next_sms(smsq); - if (!sms) + if (!sms) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (%d attempted)\n", + attempted); break; + } rounds += 1; + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds); /* * This code needs to detect a loop. It assumes that no SMS @@ -243,6 +247,8 @@ first_sub = sms->receiver->id; initialized = 1; } else if (first_sub == sms->receiver->id) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (loop) (%d attempted)\n", + attempted); sms_free(sms); break; } @@ -324,6 +330,7 @@ */ int sms_queue_trigger(struct gsm_sms_queue *smsq) { + LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n"); if (osmo_timer_pending(&smsq->push_queue)) return 0; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index fd3771a..6f0006c 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -176,6 +176,7 @@ sms_free(sms); return CMD_WARNING; } + LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n"); sms_free(sms); sms_queue_trigger(receiver->group->net->sms_queue); -- To view, visit https://gerrit.osmocom.org/856 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 03:13:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 17 Sep 2016 03:13:22 +0000 Subject: osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 3: (3 comments) https://gerrit.osmocom.org/#/c/819/3/src/bts.h File src/bts.h: Line 199: enum maximise_direction max_ts_direction_cfgd; I read the name as "maximum timeslot direction configured", a bit confusing. How about maximise_direction like the enum, or maximise_dir? Check whether an enum in this struct is ok. Is the struct used only internally in osmo-pcu? I'm not entirely sure that I know the main reasons, but sometimes we prefer an int. (When you were using a uint8_t in a previous version I assumed it was to avoid an enum for ABI / encoding reasons.) https://gerrit.osmocom.org/#/c/819/3/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 778: if (bts->max_ts_direction_cfgd == UL_ONLY) { switch() ? https://gerrit.osmocom.org/#/c/819/3/src/pcu_vty.c File src/pcu_vty.c: Line 512: bts->max_ts_direction_cfgd = UL_ONLY; I see you've removed the final else, but I think there should be a way to switch it back to the default. Maybe a 'no maximise-direction' could make sense, or 'maximise-direction none'? -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:41:04 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:41:04 +0000 Subject: openbsc[master]: Sanity fixes for gsm0408_dispatch(): rc, assertions In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/855 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:41:22 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:41:22 +0000 Subject: openbsc[master]: properly #include from gsm_subscriber.h In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/850 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaa3dc36768f96f6b8c91010a2ba389fdc37f1503 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:41:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:41:42 +0000 Subject: openbsc[master]: vty l3 help: fix typo 'comamnds'; fix english s/his// In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/852 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6be52bbb69de8aa0a6d57a3a320661ad85fc2cc4 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:42:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:42:39 +0000 Subject: openbsc[master]: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/853 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:43:26 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:43:26 +0000 Subject: openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:44:14 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:44:14 +0000 Subject: openbsc[master]: debug log for sms: fix/add In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/856 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:44:41 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:44:41 +0000 Subject: openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Alexander Huemer Gerrit-Reviewer: Alexander Huemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:44:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:44:47 +0000 Subject: [MERGED] openbsc[master]: Consistenly format variables in */Makefile.am files In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Consistenly format variables in */Makefile.am files ...................................................................... Consistenly format variables in */Makefile.am files Change-Id: Ifa21513c007072314097b7bec188579972dc1694 --- M openbsc/Makefile.am M openbsc/doc/Makefile.am M openbsc/doc/examples/Makefile.am M openbsc/include/Makefile.am M openbsc/include/openbsc/Makefile.am M openbsc/src/Makefile.am M openbsc/src/gprs/Makefile.am M openbsc/src/ipaccess/Makefile.am M openbsc/src/libbsc/Makefile.am M openbsc/src/libcommon/Makefile.am M openbsc/src/libfilter/Makefile.am M openbsc/src/libiu/Makefile.am M openbsc/src/libmgcp/Makefile.am M openbsc/src/libmsc/Makefile.am M openbsc/src/libtrau/Makefile.am M openbsc/src/osmo-bsc/Makefile.am M openbsc/src/osmo-bsc_mgcp/Makefile.am M openbsc/src/osmo-bsc_nat/Makefile.am M openbsc/src/osmo-nitb/Makefile.am M openbsc/src/utils/Makefile.am M openbsc/tests/Makefile.am M openbsc/tests/abis/Makefile.am M openbsc/tests/bsc-nat/Makefile.am M openbsc/tests/bsc/Makefile.am M openbsc/tests/channel/Makefile.am M openbsc/tests/db/Makefile.am M openbsc/tests/gbproxy/Makefile.am M openbsc/tests/gsm0408/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mgcp/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/oap/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/smpp/Makefile.am M openbsc/tests/subscr/Makefile.am M openbsc/tests/trau/Makefile.am M openbsc/tests/xid/Makefile.am 37 files changed, 1,481 insertions(+), 471 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am index 8696eb4..f7eda56 100644 --- a/openbsc/Makefile.am +++ b/openbsc/Makefile.am @@ -1,7 +1,16 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = doc include src tests +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +SUBDIRS = \ + doc \ + include \ + src \ + tests \ + $(NULL) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = openbsc.pc diff --git a/openbsc/doc/Makefile.am b/openbsc/doc/Makefile.am index aee2d7b..5a23107 100644 --- a/openbsc/doc/Makefile.am +++ b/openbsc/doc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = examples +SUBDIRS = \ + examples \ + $(NULL) diff --git a/openbsc/doc/examples/Makefile.am b/openbsc/doc/examples/Makefile.am index 8f14fdc..530c3fa 100644 --- a/openbsc/doc/examples/Makefile.am +++ b/openbsc/doc/examples/Makefile.am @@ -1,4 +1,3 @@ - CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' dist-hook: diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am index 4596b6e..3234e62 100644 --- a/openbsc/include/Makefile.am +++ b/openbsc/include/Makefile.am @@ -1,3 +1,8 @@ -SUBDIRS = openbsc +SUBDIRS = \ + openbsc \ + $(NULL) -noinst_HEADERS = mISDNif.h compat_af_isdn.h +noinst_HEADERS = \ + mISDNif.h \ + compat_af_isdn.h \ + $(NULL) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 90aa364..cae8ba4 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -1,25 +1,87 @@ -noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ - gsm_subscriber.h gsm_04_11.h debug.h signal.h \ - misdn.h chan_alloc.h paging.h ctrl.h \ - trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \ - bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ - silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h \ - vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \ - handover_decision.h rrlp.h \ - crc24.h gprs_llc.h gprs_gmm.h \ - gb_proxy.h gprs_sgsn.h sgsn.h \ - auth.h osmo_msc.h bsc_msc.h bsc_nat.h \ - osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \ - osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.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_client.h bsc_msg_filter.h \ - oap.h oap_messages.h \ - gtphub.h gprs_llc_xid.h gprs_sndcp.h \ - iu.h +noinst_HEADERS = \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bss.h \ + chan_alloc.h \ + crc24.h \ + ctrl.h \ + db.h \ + debug.h \ + e1_config.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_gsup_client.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp.h \ + gprs_utils.h \ + gsm_04_08.h \ + gsm_04_11.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + gtphub.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ + iu.h \ + meas_feed.h \ + meas_rep.h \ + mgcp.h \ + mgcp_internal.h \ + mgcp_transcode.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + nat_rewrite_trie.h \ + network_listen.h \ + oap.h \ + oap_messages.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_msc_data.h \ + osmux.h \ + paging.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + smpp.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + token_auth.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + $(NULL) -openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h -openbscdir = $(includedir)/openbsc +openbsc_HEADERS = \ + bsc_api.h \ + gsm_04_08.h \ + meas_rep.h \ + $(NULL) + +openbscdir = \ + $(includedir)/openbsc \ + $(NULL) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 4aa880f..272292a 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -1,22 +1,59 @@ -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) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) # Libraries -SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter +SUBDIRS = \ + libcommon \ + libmgcp \ + libbsc \ + libmsc \ + libtrau \ + libfilter \ + $(NULL) # Conditional Libraries if BUILD_IU -SUBDIRS += libiu +SUBDIRS += \ + libiu \ + $(NULL) endif # Programs -SUBDIRS += osmo-nitb osmo-bsc_mgcp utils ipaccess gprs +SUBDIRS += \ + osmo-nitb \ + osmo-bsc_mgcp \ + utils \ + ipaccess \ + gprs \ + $(NULL) # Conditional Programs if BUILD_NAT -SUBDIRS += osmo-bsc_nat +SUBDIRS += \ + osmo-bsc_nat \ + $(NULL) endif + if BUILD_BSC -SUBDIRS += osmo-bsc +SUBDIRS += \ + osmo-bsc \ + $(NULL) endif diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 6a95315..02c8878 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -1,50 +1,126 @@ -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) \ - $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(NULL) -bin_PROGRAMS = osmo-gbproxy - +bin_PROGRAMS = \ + osmo-gbproxy \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -bin_PROGRAMS += osmo-sgsn osmo-gtphub +bin_PROGRAMS += \ + osmo-sgsn \ + osmo-gtphub \ + $(NULL) endif endif -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) $(LIBCRYPTO_LIBS) -lrt +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 \ + $(NULL) +osmo_gbproxy_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) -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_utils.c gprs_gsup_client.c \ - sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a +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_utils.c \ + gprs_gsup_client.c \ + sgsn_cdr.c \ + sgsn_ares.c \ + oap.c \ + oap_messages.c \ + gprs_llc_xid.c \ + $(NULL) +osmo_sgsn_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) if BUILD_IU -osmo_sgsn_LDADD += $(top_builddir)/src/libiu/libiu.a -endif -osmo_sgsn_LDADD += -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) -lrt -if BUILD_IU -osmo_sgsn_LDADD += $(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS) +osmo_sgsn_LDADD += \ + $(top_builddir)/src/libiu/libiu.a \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) endif -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 +osmo_gtphub_SOURCES = \ + gtphub_main.c \ + gtphub.c \ + gtphub_sock.c \ + gtphub_ares.c \ + gtphub_vty.c \ + sgsn_ares.c \ + gprs_utils.c \ + $(NULL) +osmo_gtphub_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCARES_LIBS) \ + -lrt \ + -lgtp \ + $(NULL) diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am index 9acc0f7..784a578 100644 --- a/openbsc/src/ipaccess/Makefile.am +++ b/openbsc/src/ipaccess/Makefile.am @@ -1,26 +1,66 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) -OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = abisip-find ipaccess-config ipaccess-proxy +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -abisip_find_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) -abisip_find_SOURCES = abisip-find.c +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -ipaccess_config_SOURCES = ipaccess-config.c ipaccess-firmware.c network_listen.c +OSMO_LIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +bin_PROGRAMS = \ + abisip-find \ + ipaccess-config \ + ipaccess-proxy \ + $(NULL) + +abisip_find_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) + +abisip_find_SOURCES = \ + abisip-find.c \ + $(NULL) + +ipaccess_config_SOURCES = \ + ipaccess-config.c \ + ipaccess-firmware.c \ + network_listen.c \ + $(NULL) # FIXME: resolve the bogus dependencies patched around here: -ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBCRYPT) $(OSMO_LIBS) +ipaccess_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(OSMO_LIBS) \ + $(NULL) -ipaccess_proxy_SOURCES = ipaccess-proxy.c -ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) +ipaccess_proxy_SOURCES = \ + ipaccess-proxy.c \ + $(NULL) + +ipaccess_proxy_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(OSMO_LIBS) \ + $(NULL) diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am index fd8de0e..4728e23 100644 --- a/openbsc/src/libbsc/Makefile.am +++ b/openbsc/src/libbsc/Makefile.am @@ -1,28 +1,53 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libbsc.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libbsc_a_SOURCES = abis_nm.c abis_nm_vty.c \ - abis_om2000.c abis_om2000_vty.c \ - abis_rsl.c bsc_rll.c \ - paging.c \ - bts_ericsson_rbs2000.c \ - bts_ipaccess_nanobts.c \ - bts_siemens_bs11.c \ - bts_nokia_site.c \ - bts_unknown.c \ - bts_sysmobts.c \ - chan_alloc.c \ - handover_decision.c handover_logic.c meas_rep.c \ - rest_octets.c system_information.c \ - e1_config.c \ - bsc_api.c bsc_msc.c bsc_vty.c \ - gsm_04_08_utils.c \ - bsc_init.c bts_init.c bsc_rf_ctrl.c \ - arfcn_range_encode.c bsc_ctrl_commands.c \ - bsc_ctrl_lookup.c \ - net_init.c \ - bsc_dyn_ts.c +noinst_LIBRARIES = \ + libbsc.a \ + $(NULL) + +libbsc_a_SOURCES = \ + abis_nm.c \ + abis_nm_vty.c \ + abis_om2000.c \ + abis_om2000_vty.c \ + abis_rsl.c \ + bsc_rll.c \ + paging.c \ + bts_ericsson_rbs2000.c \ + bts_ipaccess_nanobts.c \ + bts_siemens_bs11.c \ + bts_nokia_site.c \ + bts_unknown.c \ + bts_sysmobts.c \ + chan_alloc.c \ + handover_decision.c \ + handover_logic.c \ + meas_rep.c \ + rest_octets.c \ + system_information.c \ + e1_config.c \ + bsc_api.c \ + bsc_msc.c bsc_vty.c \ + gsm_04_08_utils.c \ + bsc_init.c \ + bts_init.c \ + bsc_rf_ctrl.c \ + arfcn_range_encode.c \ + bsc_ctrl_commands.c \ + bsc_ctrl_lookup.c \ + net_init.c \ + bsc_dyn_ts.c \ + $(NULL) diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am index 75f40ee..6cfebc2 100644 --- a/openbsc/src/libcommon/Makefile.am +++ b/openbsc/src/libcommon/Makefile.am @@ -1,9 +1,29 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libcommon.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \ - gsm_data_shared.c socket.c talloc_ctx.c \ - gsm_subscriber_base.c +noinst_LIBRARIES = \ + libcommon.a \ + $(NULL) + +libcommon_a_SOURCES = \ + bsc_version.c \ + common_vty.c \ + debug.c \ + gsm_data.c \ + gsm_data_shared.c \ + socket.c \ + talloc_ctx.c \ + gsm_subscriber_base.c \ + $(NULL) diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am index ed3cd43..6d3db0b 100644 --- a/openbsc/src/libfilter/Makefile.am +++ b/openbsc/src/libfilter/Makefile.am @@ -1,11 +1,26 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libfilter.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libfilter.a \ + $(NULL) libfilter_a_SOURCES = \ bsc_msg_filter.c \ bsc_msg_acc.c \ - bsc_msg_vty.c + bsc_msg_vty.c \ + $(NULL) diff --git a/openbsc/src/libiu/Makefile.am b/openbsc/src/libiu/Makefile.am index 1968d3e..e5f9e27 100644 --- a/openbsc/src/libiu/Makefile.am +++ b/openbsc/src/libiu/Makefile.am @@ -1,10 +1,28 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) \ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libiu.a +noinst_LIBRARIES = \ + libiu.a \ + $(NULL) -libiu_a_SOURCES = iu.c iu_vty.c +libiu_a_SOURCES = \ + iu.c \ + iu_vty.c \ + $(NULL) diff --git a/openbsc/src/libmgcp/Makefile.am b/openbsc/src/libmgcp/Makefile.am index 4403d60..5faf602 100644 --- a/openbsc/src/libmgcp/Makefile.am +++ b/openbsc/src/libmgcp/Makefile.am @@ -1,16 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(COVERAGE_LDFLAGS) $(LIBBCG729_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libmgcp.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_HEADERS = g711common.h +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBBCG729_LIBS) \ + $(NULL) -libmgcp_a_SOURCES = mgcp_protocol.c mgcp_network.c mgcp_vty.c mgcp_osmux.c \ - mgcp_sdp.c +noinst_LIBRARIES = \ + libmgcp.a \ + $(NULL) +noinst_HEADERS = \ + g711common.h \ + $(NULL) + +libmgcp_a_SOURCES = \ + mgcp_protocol.c \ + mgcp_network.c \ + mgcp_vty.c \ + mgcp_osmux.c \ + mgcp_sdp.c \ + $(NULL) if BUILD_MGCP_TRANSCODING - libmgcp_a_SOURCES += mgcp_transcode.c +libmgcp_a_SOURCES += \ + mgcp_transcode.c \ + $(NULL) endif diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am index 5195890..d236d3a 100644 --- a/openbsc/src/libmsc/Makefile.am +++ b/openbsc/src/libmsc/Makefile.am @@ -1,27 +1,59 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_feed.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_LIBRARIES = libmsc.a +noinst_HEADERS = \ + meas_feed.h \ + $(NULL) -libmsc_a_SOURCES = auth.c \ - db.c \ - gsm_04_08.c gsm_04_11.c gsm_04_11_helper.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c mncc_builtin.c mncc_sock.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - token_auth.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c ctrl_commands.c meas_feed.c +noinst_LIBRARIES = \ + libmsc.a \ + $(NULL) + +libmsc_a_SOURCES = \ + auth.c \ + db.c \ + gsm_04_08.c \ + gsm_04_11.c \ + gsm_04_11_helper.c \ + gsm_04_80.c \ + gsm_subscriber.c \ + mncc.c \ + mncc_builtin.c \ + mncc_sock.c \ + rrlp.c \ + silent_call.c \ + sms_queue.c \ + token_auth.c \ + ussd.c \ + vty_interface_layer3.c \ + transaction.c \ + osmo_msc.c \ + ctrl_commands.c \ + meas_feed.c \ + $(NULL) if BUILD_SMPP -noinst_HEADERS += smpp_smsc.h -libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c +noinst_HEADERS += \ + smpp_smsc.h \ + $(NULL) + +libmsc_a_SOURCES += \ + smpp_smsc.c \ + smpp_openbsc.c \ + smpp_vty.c \ + smpp_utils.c \ + $(NULL) endif diff --git a/openbsc/src/libtrau/Makefile.am b/openbsc/src/libtrau/Makefile.am index 0fe3a53..46becd6 100644 --- a/openbsc/src/libtrau/Makefile.am +++ b/openbsc/src/libtrau/Makefile.am @@ -1,7 +1,31 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_LIBRARIES = libtrau.a +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -libtrau_a_SOURCES = rtp_proxy.c trau_mux.c trau_upqueue.c +AM_LDFLAGS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_LIBRARIES = \ + libtrau.a \ + $(NULL) + +libtrau_a_SOURCES = \ + rtp_proxy.c \ + trau_mux.c \ + trau_upqueue.c \ + $(NULL) diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 4aa1803..2dbfeb8 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -1,21 +1,55 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ - osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c +bin_PROGRAMS = \ + osmo-bsc \ + $(NULL) + +osmo_bsc_SOURCES = \ + osmo_bsc_main.c \ + osmo_bsc_vty.c \ + osmo_bsc_api.c \ + osmo_bsc_grace.c \ + osmo_bsc_msc.c \ + osmo_bsc_sccp.c \ + osmo_bsc_filter.c \ + osmo_bsc_bssap.c \ + osmo_bsc_audio.c \ + osmo_bsc_ctrl.c \ + $(NULL) + # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_mgcp/Makefile.am b/openbsc/src/osmo-bsc_mgcp/Makefile.am index a48f24b..a19a4eb 100644 --- a/openbsc/src/osmo-bsc_mgcp/Makefile.am +++ b/openbsc/src/osmo-bsc_mgcp/Makefile.am @@ -1,14 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_mgcp +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -osmo_bsc_mgcp_SOURCES = mgcp_main.c +bin_PROGRAMS = \ + osmo-bsc_mgcp \ + $(NULL) -osmo_bsc_mgcp_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libmgcp/libmgcp.a -lrt \ - $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBOSMONETIF_LIBS) $(LIBBCG729_LIBS) \ - $(LIBRARY_GSM) +osmo_bsc_mgcp_SOURCES = \ + mgcp_main.c \ + $(NULL) + +osmo_bsc_mgcp_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-bsc_nat/Makefile.am b/openbsc/src/osmo-bsc_nat/Makefile.am index 4a6f74d..6027f27 100644 --- a/openbsc/src/osmo-bsc_nat/Makefile.am +++ b/openbsc/src/osmo-bsc_nat/Makefile.am @@ -1,19 +1,57 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBCRYPTO_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -bin_PROGRAMS = osmo-bsc_nat +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_bsc_nat_SOURCES = bsc_filter.c bsc_mgcp_utils.c bsc_nat.c bsc_nat_utils.c \ - bsc_nat_vty.c bsc_sccp.c bsc_ussd.c bsc_nat_ctrl.c \ - bsc_nat_rewrite.c bsc_nat_rewrite_trie.c bsc_nat_filter.c +bin_PROGRAMS = \ + osmo-bsc_nat \ + $(NULL) + +osmo_bsc_nat_SOURCES = \ + bsc_filter.c \ + bsc_mgcp_utils.c \ + bsc_nat.c \ + bsc_nat_utils.c \ + bsc_nat_vty.c \ + bsc_sccp.c \ + bsc_ussd.c \ + bsc_nat_ctrl.c \ + bsc_nat_rewrite.c \ + bsc_nat_rewrite_trie.c \ + bsc_nat_filter.c \ + $(NULL) + osmo_bsc_nat_LDADD = \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libfilter/libfilter.a \ - -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libfilter/libfilter.a \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/src/osmo-nitb/Makefile.am b/openbsc/src/osmo-nitb/Makefile.am index 3b7cc8d..60514c0 100644 --- a/openbsc/src/osmo-nitb/Makefile.am +++ b/openbsc/src/osmo-nitb/Makefile.am @@ -1,18 +1,44 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CFLAGS = \ + -Wall \ + $(COVERAGE_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = osmo-nitb +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -osmo_nitb_SOURCES = bsc_hack.c +bin_PROGRAMS = \ + osmo-nitb \ + $(NULL) + +osmo_nitb_SOURCES = \ + bsc_hack.c \ + $(NULL) + osmo_nitb_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - -ldbi $(LIBCRYPT) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) $(LIBOSMOABIS_LIBS) $(LIBSMPP34_LIBS) $(LIBCRYPTO_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBCRYPT) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 5a2e2d2..0dbb85c 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -1,42 +1,123 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(SQLITE3_CFLAGS) \ - $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir) \ + $(NULL) -noinst_HEADERS = meas_db.h +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -bin_PROGRAMS = bs11_config isdnsync +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + meas_db.h \ + $(NULL) + +bin_PROGRAMS = \ + bs11_config \ + isdnsync \ + $(NULL) if HAVE_SQLITE3 -bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db +bin_PROGRAMS += \ + osmo-meas-pcap2db \ + osmo-meas-udp2db \ + $(NULL) endif if HAVE_LIBCDK -bin_PROGRAMS += meas_vis +bin_PROGRAMS += \ + meas_vis \ + $(NULL) endif if BUILD_SMPP -noinst_PROGRAMS = smpp_mirror +noinst_PROGRAMS = \ + smpp_mirror \ + $(NULL) endif -bs11_config_SOURCES = bs11_config.c -bs11_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) +bs11_config_SOURCES = \ + bs11_config.c \ + $(NULL) -isdnsync_SOURCES = isdnsync.c +bs11_config_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) -smpp_mirror_SOURCES = smpp_mirror.c -smpp_mirror_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) +isdnsync_SOURCES = \ + isdnsync.c \ + $(NULL) -meas_vis_SOURCES = meas_vis.c -meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses -meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_SOURCES = \ + smpp_mirror.c \ + $(NULL) -osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c -osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS) -osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +smpp_mirror_LDADD = \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(NULL) -osmo_meas_udp2db_SOURCES = meas_udp2db.c meas_db.c -osmo_meas_udp2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(SQLITE3_LIBS) -osmo_meas_udp2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +meas_vis_SOURCES = \ + meas_vis.c \ + $(NULL) + +meas_vis_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + -lcdk \ + -lncurses \ + $(NULL) + +meas_vis_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_pcap2db_SOURCES = \ + meas_pcap2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_pcap2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + -lpcap \ + $(NULL) + +osmo_meas_pcap2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +osmo_meas_udp2db_SOURCES = \ + meas_udp2db.c \ + meas_db.c \ + $(NULL) + +osmo_meas_udp2db_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +osmo_meas_udp2db_CFLAGS = \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index ba5ca28..7396c52 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,24 +1,44 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid - +SUBDIRS = \ + gsm0408 \ + db \ + channel \ + mgcp \ + gprs \ + abis \ + gbproxy \ + trau \ + subscr \ + mm_auth \ + xid \ + $(NULL) if BUILD_NAT -SUBDIRS += bsc-nat bsc-nat-trie +SUBDIRS += \ + bsc-nat \ + bsc-nat-trie \ + $(NULL) endif - if BUILD_BSC -SUBDIRS += bsc +SUBDIRS += \ + bsc \ + $(NULL) endif - if BUILD_SMPP -SUBDIRS += smpp +SUBDIRS += \ + smpp \ + $(NULL) endif - if HAVE_LIBGTP -SUBDIRS += gtphub -if HAVE_LIBCARES -SUBDIRS += sgsn oap -endif -endif +SUBDIRS += \ + gtphub \ + $(NULL) +if HAVE_LIBCARES +SUBDIRS += \ + sgsn \ + oap \ + $(NULL) +endif +endif # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -38,9 +58,20 @@ echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) vty_test_runner.py ctrl_test_runner.py smpp_test_runner.py +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + vty_test_runner.py \ + ctrl_test_runner.py \ + smpp_test_runner.py \ + $(NULL) + TESTSUITE = $(srcdir)/testsuite -DISTCLEANFILES = atconfig + +DISTCLEANFILES = \ + atconfig \ + $(NULL) if ENABLE_EXT_TESTS python-tests: $(BUILT_SOURCES) diff --git a/openbsc/tests/abis/Makefile.am b/openbsc/tests/abis/Makefile.am index c2e38de..cbc3e07 100644 --- a/openbsc/tests/abis/Makefile.am +++ b/openbsc/tests/abis/Makefile.am @@ -1,17 +1,35 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) $(COVERAGE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = abis_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = abis_test +EXTRA_DIST = \ + abis_test.ok \ + $(NULL) -abis_test_SOURCES = abis_test.c +noinst_PROGRAMS = \ + abis_test \ + $(NULL) + +abis_test_SOURCES = \ + abis_test.c \ + $(NULL) abis_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 26e5500..fa55d27 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -1,26 +1,58 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_nat_test.ok bsc_data.c barr.cfg barr_dup.cfg prefixes.csv +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_nat_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_nat_test_SOURCES = bsc_nat_test.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ - $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c +EXTRA_DIST = \ + bsc_nat_test.ok \ + bsc_data.c \ + barr.cfg \ + barr_dup.cfg \ + prefixes.csv \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_nat_test \ + $(NULL) + +bsc_nat_test_SOURCES = \ + bsc_nat_test.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_sccp.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_mgcp_utils.c \ + $(top_srcdir)/src/osmo-bsc_nat/bsc_nat_filter.c + bsc_nat_test_LDADD = \ - $(top_builddir)/src/libfilter/libfilter.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMONETIF_LIBS) \ - $(LIBOSMOCTRL_LIBS) + $(top_builddir)/src/libfilter/libfilter.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am index 8b786ff..ddfa437 100644 --- a/openbsc/tests/bsc/Makefile.am +++ b/openbsc/tests/bsc/Makefile.am @@ -1,18 +1,45 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = bsc_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = bsc_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -bsc_test_SOURCES = bsc_test.c \ - $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c -bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) +EXTRA_DIST = \ + bsc_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + bsc_test \ + $(NULL) + +bsc_test_SOURCES = \ + bsc_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(NULL) + +bsc_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am index 51b2f83..5654572 100644 --- a/openbsc/tests/channel/Makefile.am +++ b/openbsc/tests/channel/Makefile.am @@ -1,14 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = channel_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = channel_test +EXTRA_DIST = \ + channel_test.ok \ + $(NULL) -channel_test_SOURCES = channel_test.c +noinst_PROGRAMS = \ + channel_test \ + $(NULL) + +channel_test_SOURCES = \ + channel_test.c \ + $(NULL) + channel_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ - -ldbi $(LIBOSMOGSM_LIBS) $(LIBCRYPTO_LIBS) + $(LIBOSMOGSM_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am index be3af5f..c4da31c 100644 --- a/openbsc/tests/db/Makefile.am +++ b/openbsc/tests/db/Makefile.am @@ -1,17 +1,48 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = db_test.ok db_test.err hlr.sqlite3 +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = db_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -db_test_SOURCES = db_test.c -db_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBCRYPTO_LIBS) -ldbi +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + hlr.sqlite3 \ + $(NULL) + +noinst_PROGRAMS = \ + db_test \ + $(NULL) + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gbproxy/Makefile.am b/openbsc/tests/gbproxy/Makefile.am index 18d77a8..2dd66df 100644 --- a/openbsc/tests/gbproxy/Makefile.am +++ b/openbsc/tests/gbproxy/Makefile.am @@ -1,27 +1,54 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gbproxy_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = gbproxy_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -gbproxy_test_SOURCES = gbproxy_test.c +EXTRA_DIST = \ + gbproxy_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + gbproxy_test \ + $(NULL) + +gbproxy_test_SOURCES = \ + gbproxy_test.c \ + $(NULL) + gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes + -Wl,--wrap=RAND_bytes \ + $(NULL) + gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) -lrt + $(top_builddir)/src/gprs/gb_proxy.o \ + $(top_builddir)/src/gprs/gb_proxy_patch.o \ + $(top_builddir)/src/gprs/gb_proxy_peer.o \ + $(top_builddir)/src/gprs/gb_proxy_tlli.o \ + $(top_builddir)/src/gprs/gprs_gb_parse.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBRARY_DL) \ + $(LIBCRYPTO_LIBS) \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index 79fb9f1..11fa6b9 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -1,12 +1,34 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) -noinst_PROGRAMS = gsm0408_test +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = gsm0408_test.ok +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) -gsm0408_test_SOURCES = gsm0408_test.c -gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) -ldbi +noinst_PROGRAMS = \ + gsm0408_test \ + $(NULL) + +EXTRA_DIST = \ + gsm0408_test.ok \ + $(NULL) + +gsm0408_test_SOURCES = \ + gsm0408_test.c \ + $(NULL) + +gsm0408_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..137924d 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -1,24 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) EXTRA_DIST = \ - gtphub_test.ok + gtphub_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = gtphub_test +noinst_PROGRAMS = \ + gtphub_test \ + $(NULL) endif endif -gtphub_test_SOURCES = gtphub_test.c +gtphub_test_SOURCES = \ + gtphub_test.c \ + $(NULL) + gtphub_test_LDFLAGS = \ -Wl,--wrap=gtphub_resolve_ggsn_addr \ -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write + -Wl,--wrap=gtphub_write \ + $(NULL) gtphub_test_LDADD = \ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp -lrt - + -lgtp \ + -lrt \ + $(NULL) diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 82d6ac6..4b18036 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -1,30 +1,72 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir) -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_FLAGS) $(LIBOSMONETIF_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) $(LIBBCG729_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir) \ + $(NULL) -EXTRA_DIST = mgcp_test.ok mgcp_transcoding_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_FLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBBCG729_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = mgcp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) +EXTRA_DIST = \ + mgcp_test.ok \ + mgcp_transcoding_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + mgcp_test \ + $(NULL) if BUILD_MGCP_TRANSCODING -noinst_PROGRAMS += mgcp_transcoding_test +noinst_PROGRAMS += \ + mgcp_transcoding_test \ + $(NULL) endif -mgcp_test_SOURCES = mgcp_test.c +mgcp_test_SOURCES = \ + mgcp_test.c \ + $(NULL) -mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) +mgcp_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + -lrt \ + -lm \ + $(NULL) -mgcp_transcoding_test_SOURCES = mgcp_transcoding_test.c +mgcp_transcoding_test_SOURCES = \ + mgcp_transcoding_test.c \ + $(NULL) mgcp_transcoding_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmgcp/libmgcp.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ - $(LIBBCG729_LIBS) -lrt -lm $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ - $(LIBRARY_DL) $(LIBOSMONETIF_LIBS) $(LIBRARY_GSM) + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmgcp/libmgcp.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBBCG729_LIBS) \ + $(LIBOSMOSCCP_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBRARY_GSM) \ + -lrt \ + -lm \ + $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 516df00..7eb14fa 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -1,21 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -noinst_PROGRAMS = mm_auth_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ + $(NULL) -EXTRA_DIST = mm_auth_test.ok +noinst_PROGRAMS = \ + mm_auth_test \ + $(NULL) -mm_auth_test_SOURCES = mm_auth_test.c +EXTRA_DIST = \ + mm_auth_test.ok \ + $(NULL) + +mm_auth_test_SOURCES = \ + mm_auth_test.c \ + $(NULL) mm_auth_test_LDFLAGS = \ -Wl,--wrap=db_get_authinfo_for_subscr \ -Wl,--wrap=db_get_lastauthtuple_for_subscr \ - -Wl,--wrap=db_sync_lastauthtuple_for_subscr + -Wl,--wrap=db_sync_lastauthtuple_for_subscr \ + $(NULL) -mm_auth_test_LDADD = $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) +mm_auth_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/oap/Makefile.am b/openbsc/tests/oap/Makefile.am index 538e178..06ccf33 100644 --- a/openbsc/tests/oap/Makefile.am +++ b/openbsc/tests/oap/Makefile.am @@ -1,15 +1,30 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = oap_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + oap_test.ok \ + $(NULL) if HAVE_LIBGTP if HAVE_LIBCARES -noinst_PROGRAMS = oap_test +noinst_PROGRAMS = \ + oap_test \ + $(NULL) endif endif -oap_test_SOURCES = oap_test.c +oap_test_SOURCES = \ + oap_test.c \ + $(NULL) oap_test_LDADD = \ $(top_builddir)/src/gprs/oap.o \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index ce64429..6371707 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -1,20 +1,42 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) if BUILD_IU -AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS) +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) endif -EXTRA_DIST = sgsn_test.ok +EXTRA_DIST = \ + sgsn_test.ok \ + $(NULL) -noinst_PROGRAMS = sgsn_test +noinst_PROGRAMS = \ + sgsn_test \ + $(NULL) -sgsn_test_SOURCES = sgsn_test.c +sgsn_test_SOURCES = \ + sgsn_test.c \ + $(NULL) + sgsn_test_LDFLAGS = \ -Wl,--wrap=RAND_bytes \ -Wl,--wrap=sgsn_update_subscriber_data \ -Wl,--wrap=gprs_subscr_request_update_location \ -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gprs_gsup_client_send + -Wl,--wrap=gprs_gsup_client_send \ + $(NULL) sgsn_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_parse.o \ @@ -33,7 +55,7 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -41,12 +63,14 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt + -lgtp \ + -lrt \ + $(NULL) if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) + $(LIBASN1C_LIBS) \ + $(NULL) endif - diff --git a/openbsc/tests/smpp/Makefile.am b/openbsc/tests/smpp/Makefile.am index aab4de9..5082707 100644 --- a/openbsc/tests/smpp/Makefile.am +++ b/openbsc/tests/smpp/Makefile.am @@ -1,13 +1,40 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBSMPP34_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/libmsc \ + $(NULL) -EXTRA_DIST = smpp_test.ok smpp_test.err +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = smpp_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -smpp_test_SOURCES = smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c +EXTRA_DIST = \ + smpp_test.ok \ + smpp_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + smpp_test \ + $(NULL) + +smpp_test_SOURCES = \ + smpp_test.c \ + $(top_builddir)/src/libmsc/smpp_utils.c \ + $(NULL) + smpp_test_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(NULL) diff --git a/openbsc/tests/subscr/Makefile.am b/openbsc/tests/subscr/Makefile.am index 4f96dc9..fb863d8 100644 --- a/openbsc/tests/subscr/Makefile.am +++ b/openbsc/tests/subscr/Makefile.am @@ -1,18 +1,43 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = subscr_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = subscr_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -subscr_test_SOURCES = subscr_test.c -subscr_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) -# -ldbi +EXTRA_DIST = \ + subscr_test.ok \ + $(NULL) +noinst_PROGRAMS = \ + subscr_test \ + $(NULL) + +subscr_test_SOURCES = \ + subscr_test.c \ + $(NULL) + +subscr_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(NULL) diff --git a/openbsc/tests/trau/Makefile.am b/openbsc/tests/trau/Makefile.am index cc1b4ef..93ce88e 100644 --- a/openbsc/tests/trau/Makefile.am +++ b/openbsc/tests/trau/Makefile.am @@ -1,17 +1,46 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(COVERAGE_LDFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = trau_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = trau_test +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + $(NULL) -trau_test_SOURCES = trau_test.c -trau_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBSMPP34_LIBS) $(LIBOSMOVTY_LIBS) $(LIBRARY_DL) -ldbi +EXTRA_DIST = \ + trau_test.ok \ + $(NULL) + +noinst_PROGRAMS = \ + trau_test \ + $(NULL) + +trau_test_SOURCES = \ + trau_test.c \ + $(NULL) + +trau_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBSMPP34_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) \ + -ldbi \ + $(NULL) diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index 9b64965..e7c4cf0 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -1,11 +1,27 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) -EXTRA_DIST = xid_test.ok +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(NULL) -noinst_PROGRAMS = xid_test +EXTRA_DIST = \ + xid_test.ok \ + $(NULL) -xid_test_SOURCES = xid_test.c +noinst_PROGRAMS = \ + xid_test \ + $(NULL) + +xid_test_SOURCES = \ + xid_test.c \ + $(NULL) xid_test_LDADD = \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ @@ -16,6 +32,8 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp -lrt -lm - + -lgtp \ + -lrt \ + -lm \ + $(NULL) -- To view, visit https://gerrit.osmocom.org/838 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifa21513c007072314097b7bec188579972dc1694 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Alexander Huemer Gerrit-Reviewer: Alexander Huemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:44:50 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:44:50 +0000 Subject: [MERGED] openbsc[master]: Build fixes In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Build fixes ...................................................................... Build fixes Some fixes for build environments where dependencies are installed in distinct directories. Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 --- M openbsc/src/gprs/Makefile.am M openbsc/tests/gtphub/Makefile.am M openbsc/tests/mm_auth/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/xid/Makefile.am 5 files changed, 10 insertions(+), 4 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 02c8878..59136bd 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -28,10 +28,12 @@ OSMO_LIBS = \ $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOABIS_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOGB_LIBS) \ + $(LIBGTP_LIBS) \ $(NULL) bin_PROGRAMS = \ @@ -121,6 +123,6 @@ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ $(LIBCARES_LIBS) \ + $(LIBGTP_LIBS) \ -lrt \ - -lgtp \ $(NULL) diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index 137924d..5c834b7 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -7,6 +7,8 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBGTP_CFLAGS) \ $(NULL) EXTRA_DIST = \ @@ -35,6 +37,6 @@ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) diff --git a/openbsc/tests/mm_auth/Makefile.am b/openbsc/tests/mm_auth/Makefile.am index 7eb14fa..cb35198 100644 --- a/openbsc/tests/mm_auth/Makefile.am +++ b/openbsc/tests/mm_auth/Makefile.am @@ -6,6 +6,7 @@ AM_CFLAGS = \ -Wall \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCRYPTO_CFLAGS) \ $(NULL) diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 6371707..d148c48 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -7,6 +7,7 @@ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ $(LIBCARES_CFLAGS) \ $(NULL) @@ -63,7 +64,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ $(NULL) if BUILD_IU diff --git a/openbsc/tests/xid/Makefile.am b/openbsc/tests/xid/Makefile.am index e7c4cf0..aaf17ed 100644 --- a/openbsc/tests/xid/Makefile.am +++ b/openbsc/tests/xid/Makefile.am @@ -32,7 +32,7 @@ $(LIBOSMOGB_LIBS) \ $(LIBCARES_LIBS) \ $(LIBCRYPTO_LIBS) \ - -lgtp \ + $(LIBGTP_LIBS) \ -lrt \ -lm \ $(NULL) -- To view, visit https://gerrit.osmocom.org/839 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I38808fd2911747b266ee6fde91187a88dd7ae355 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Alexander Huemer Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:45:08 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:45:08 +0000 Subject: [MERGED] openbsc[master]: sms: change rp err cause of smpp_try_deliver errors In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sms: change rp err cause of smpp_try_deliver errors ...................................................................... sms: change rp err cause of smpp_try_deliver errors smpp_try_deliver could fail with rc < 0. In such cases don't send the MS the rp error sms rejected (cause 21). A rejected message should not be sent again. The spec 04 11 recommends sending cause 41 Temporary failure in unknown cases. Add also a log message and rate counter for such cases. Tweaked-By: Neels Hofmeyr Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libmsc/gsm_04_11.c 2 files changed, 15 insertions(+), 4 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index daa5a4d..939e0ee 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -198,6 +198,7 @@ MSC_CTR_SMS_DELIVERED, MSC_CTR_SMS_RP_ERR_MEM, MSC_CTR_SMS_RP_ERR_OTHER, + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR, MSC_CTR_CALL_MO_SETUP, MSC_CTR_CALL_MO_CONNECT_ACK, MSC_CTR_CALL_MT_SETUP, @@ -216,6 +217,7 @@ [MSC_CTR_SMS_DELIVERED] = {"sms.delivered", "Global SMS Deliver attempts."}, [MSC_CTR_SMS_RP_ERR_MEM] = {"sms.rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."}, [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms.rp_err_other", "Other error of MS responses on a sms delive attempt."}, + [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "Unknown error occured during sms delivery."}, /* FIXME: count also sms delivered */ [MSC_CTR_CALL_MO_SETUP] = {"call.mo_setup", "Received setup requests from a MS to init a MO call."}, [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 6d3f41b..d1fdfb9 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -294,8 +295,12 @@ if (rc == 1) goto try_local; if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } return rc; } @@ -319,8 +324,12 @@ rc = 1; /* cause 1: unknown subscriber */ rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); } else if (rc < 0) { - rc = 21; /* cause 21: short message transfer rejected */ - /* FIXME: handle the error somehow? */ + LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", + subscr_name(conn->subscr), rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); } #else rc = 1; /* cause 1: unknown subscriber */ -- To view, visit https://gerrit.osmocom.org/551 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia03e50ce2bd9a7d1054cc5a6000fd73bd3497c03 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: lynxis lazus From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:46:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:46:58 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add EDGE MCS 1-9 definitions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1452342f524a8b60f2babc07398a1d9c9e06aa3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:47:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:47:02 +0000 Subject: libosmocore[master]: utils/conv_gen.py: add RACH, SCH and TCH/AHS definitions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/831 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0ea7151f4e8119a8798a9e129b951559e56b0d93 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 08:54:37 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 08:54:37 +0000 Subject: osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-1 (3 comments) https://gerrit.osmocom.org/#/c/691/4/src/common/l1sap.c File src/common/l1sap.c: Line 1071: msgb_put_u8(msg, marker); i think the more elegant way would be to store the marker somewhere in the msgb->cb, rather than to push it as a pseudo-header in front of the data. https://gerrit.osmocom.org/#/c/691/4/src/osmo-bts-litecell15/l1_if.c File src/osmo-bts-litecell15/l1_if.c: Line 503: if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ I think it might be more elegant to first handle the if (marker) send_onset_primitive inside an if clause and then do the common processing for actual voice data below that. But that's probably just a stylistic question. Right now in your implementation I think it's a bit un-intuitive to see what's happening. https://gerrit.osmocom.org/#/c/691/4/src/osmo-bts-litecell15/tch.c File src/osmo-bts-litecell15/tch.c: Line 337: enum osmo_amr_type ft; we don't do late variable declarations. they should be declared at the beginning of the block (which is the function in this case). -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:02:12 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:02:12 +0000 Subject: osmo-bts[master]: Use SID_FIRST_P1 to initiate DTX In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/692/1/src/osmo-bts-sysmo/tch.c File src/osmo-bts-sysmo/tch.c: Line 569: case GsmL1_TchPlType_Amr_SidFirstP1: yes, it is a work-around. but now we send two RTP SID frames for a phone that actually sends P1 and P2. Is that still spec-compliant? -- To view, visit https://gerrit.osmocom.org/692 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:03:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:03:15 +0000 Subject: osmo-pcu[master]: Handle Timing Advance IE properly In-Reply-To: References: Message-ID: Patch Set 6: > Patch Set 6: -Code-Review does that mean you no longer have any concerns regarding the merge of the patch? Did you just want to remove the negative score without any positive score? I'm not quite sure about your intention. Thanks for your clarification. -- To view, visit https://gerrit.osmocom.org/552 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I786bf7fc999d401cc3d9e7f1e7a1fba953b5d458 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:07:14 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:07:14 +0000 Subject: osmo-bts[master]: log causing rx event for lchan_lookup errors In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/746 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0d9923f47ac655b204169eec302d607412d5754d Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:07:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:07:58 +0000 Subject: openbsc[master]: log: abis_rsl: don't log 'error' when there is no error In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/749 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie0b9d62e8ce85a096c963931e0ae5527b8dc490a Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:23:39 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 17 Sep 2016 09:23:39 +0000 Subject: osmo-pcu[master]: Handle Timing Advance IE properly In-Reply-To: References: Message-ID: Patch Set 6: (1 comment) Max pointed out why it needs to be a const reference and then I removed my objection. I have had not re-read the patch then. Looking at it now it seems good to go. https://gerrit.osmocom.org/#/c/552/6/src/encoding.cpp File src/encoding.cpp: Line 39: static inline bool write_tai(bitvec *dest, unsigned& wp, int8_t tai) > Let me repeat the question. Why should wp be a mutable reference here? Max pointed out that bitvec_write_field takes a const reference to advance the write index (wi not write pointer) -- To view, visit https://gerrit.osmocom.org/552 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I786bf7fc999d401cc3d9e7f1e7a1fba953b5d458 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:58:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:58:16 +0000 Subject: osmo-bts[master]: log: sysmo,lc15: tweak log about sapi_cmds queue In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/755 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5a46c90d016cee9b50f32db2af568765d3cb74cc Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:58:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:58:28 +0000 Subject: [MERGED] osmo-bts[master]: log: sysmo, lc15: tweak log about sapi_cmds queue In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log: sysmo,lc15: tweak log about sapi_cmds queue ...................................................................... log: sysmo,lc15: tweak log about sapi_cmds queue The osmo-bts log used to say this a lot: DL1C <0006> oml.c:758 (bts=0,trx=0,ts=0,ss=1) End of queue encountered. Now empty? 1 - Move this to DEBUG level instead of NOTICE. - Tweak wording and logic so it says one of: [...] End of SAPI cmd queue encountered. Queue is now empty. [...] End of SAPI cmd queue encountered. More pending. Change-Id: I5a46c90d016cee9b50f32db2af568765d3cb74cc --- M src/osmo-bts-litecell15/oml.c M src/osmo-bts-sysmo/oml.c 2 files changed, 12 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c index a175af4..634c236 100644 --- a/src/osmo-bts-litecell15/oml.c +++ b/src/osmo-bts-litecell15/oml.c @@ -755,9 +755,12 @@ talloc_free(cmd); if (end || llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_NOTICE, - "%s End of queue encountered. Now empty? %d\n", - gsm_lchan_name(lchan), llist_empty(&lchan->sapi_cmds)); + LOGP(DL1C, LOGL_DEBUG, + "%s End of SAPI cmd queue encountered.%s\n", + gsm_lchan_name(lchan), + llist_empty(&lchan->sapi_cmds) + ? " Queue is now empty." + : " More pending."); return; } diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index dea1c5e..c1f1e0b 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -764,9 +764,12 @@ talloc_free(cmd); if (end || llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_NOTICE, - "%s End of queue encountered. Now empty? %d\n", - gsm_lchan_name(lchan), llist_empty(&lchan->sapi_cmds)); + LOGP(DL1C, LOGL_DEBUG, + "%s End of SAPI cmd queue encountered.%s\n", + gsm_lchan_name(lchan), + llist_empty(&lchan->sapi_cmds) + ? " Queue is now empty." + : " More pending."); return; } -- To view, visit https://gerrit.osmocom.org/755 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5a46c90d016cee9b50f32db2af568765d3cb74cc Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:58:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:58:47 +0000 Subject: openbsc[master]: log causing rx event for lchan_lookup errors In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/750 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id81e7b8b9c27831923f050a78dfc7d650e687033 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:58:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:58:54 +0000 Subject: [MERGED] openbsc[master]: log causing rx event for lchan_lookup errors In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log causing rx event for lchan_lookup errors ...................................................................... log causing rx event for lchan_lookup errors Add log_name to lchan_lookup() and pass such from the various RSL rx events that call it to validate the RSL chan_nr. Change-Id: Id81e7b8b9c27831923f050a78dfc7d650e687033 --- M openbsc/src/libbsc/abis_rsl.c 1 file changed, 14 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index d3d9f9e..dc4ede2 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -110,19 +110,21 @@ } /* call rsl_lchan_lookup and set the log context */ -static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr) +static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, + const char *log_name) { int rc; struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc); if (!lchan) { - LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr); + LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n", + log_name, chan_nr); return NULL; } if (rc < 0) - LOGP(DRSL, LOGL_ERROR, "%s mismatching chan_nr=0x%02x\n", - gsm_ts_and_pchan_name(lchan->ts), chan_nr); + LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n", + gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr); log_set_context(BSC_CTX_LCHAN, lchan); if (lchan->conn) @@ -1452,7 +1454,8 @@ char *ts_name; struct e1inp_sign_link *sign_link = msg->dst; - msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr); + msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr, + "Abis RSL rx DCHAN: "); ts_name = gsm_lchan_name(msg->lchan); switch (rslh->c.msg_type) { @@ -1813,7 +1816,8 @@ struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg); int rc = 0; - msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr); + msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr, + "Abis RSL rx CCHAN: "); switch (rslh->c.msg_type) { case RSL_MT_CHAN_RQD: @@ -1914,7 +1918,8 @@ char *ts_name; uint8_t sapi = rllh->link_id & 7; - msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr); + msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr, + "Abis RSL rx RLL: "); ts_name = gsm_lchan_name(msg->lchan); DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi); @@ -2308,7 +2313,8 @@ char *ts_name; int rc = 0; - msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr); + msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr, + "Abis RSL rx IPACC: "); ts_name = gsm_lchan_name(msg->lchan); switch (rllh->c.msg_type) { -- To view, visit https://gerrit.osmocom.org/750 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id81e7b8b9c27831923f050a78dfc7d650e687033 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 09:58:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 09:58:54 +0000 Subject: [MERGED] openbsc[master]: log: abis_rsl: don't log 'error' when there is no error In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log: abis_rsl: don't log 'error' when there is no error ...................................................................... log: abis_rsl: don't log 'error' when there is no error The message 'RF Channel Release due error 0' keeps catching my eye because it says 'error' even though the error code is zero, i.e. no error. This shall end now. Change-Id: Ie0b9d62e8ce85a096c963931e0ae5527b8dc490a --- M openbsc/src/libbsc/abis_rsl.c 1 file changed, 5 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 4c8448e..d3d9f9e 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -803,7 +803,11 @@ msg->lchan = lchan; msg->dst = lchan->ts->trx->rsl_link; - DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error); + if (error) + DEBUGP(DRSL, "%s RF Channel Release due to error: %d\n", + gsm_lchan_name(lchan), error); + else + DEBUGP(DRSL, "%s RF Channel Release\n", gsm_lchan_name(lchan)); if (error) { /* -- To view, visit https://gerrit.osmocom.org/749 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie0b9d62e8ce85a096c963931e0ae5527b8dc490a Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:00:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:00:52 +0000 Subject: openbsc[master]: Modify SI 13 field for control_ack_type In-Reply-To: References: Message-ID: Patch Set 8: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/546 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie869ac0a82055110f1e3b875e246750c4e113336 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:00:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:00:58 +0000 Subject: [MERGED] openbsc[master]: Modify SI 13 field for control_ack_type In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Modify SI 13 field for control_ack_type ...................................................................... Modify SI 13 field for control_ack_type Add vty function to explicitly set use of 4xRACH type of ack message for PACKET CONTROL ACKNOWLEDGMENT. Previous hardcoded value (use RLC/MAC control block) is used as a default. This is handy for debugging issues related to Timing Advance in context of GPRS. Change-Id: Ie869ac0a82055110f1e3b875e246750c4e113336 Related: OS#1526 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/rest_octets.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/rest_octets.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c 6 files changed, 47 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index ce2e9b7..7c8fb59 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -714,6 +714,7 @@ struct gsm_bts_gprs_nsvc nsvc[2]; uint8_t rac; uint8_t net_ctrl_ord; + bool ctrl_ack_type_use_block; } gprs; /* RACH NM values */ diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index b316228..3b4e598 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -89,6 +89,7 @@ uint32_t drx_timer_max;/* in seconds */ uint32_t bs_cv_max; uint8_t supports_egprs_11bit_rach; + bool ctrl_ack_type_use_block; /* use PACKET CONTROL ACKNOWLEDGMENT */ uint8_t ext_info_present; struct { diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 8116af1..f856e30 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -455,6 +455,8 @@ VTY_NEWLINE); vty_out(vty, " gprs network-control-order nc%u%s", bts->gprs.net_ctrl_ord, VTY_NEWLINE); + if (!bts->gprs.ctrl_ack_type_use_block) + vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE); vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++) @@ -2685,6 +2687,40 @@ return CMD_SUCCESS; } +DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd, + "gprs control-ack-type-rach", GPRS_TEXT + "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to " + "four access bursts format instead of default RLC/MAC control block\n") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gprs.mode == BTS_GPRS_NONE) { + vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); + return CMD_WARNING; + } + + bts->gprs.ctrl_ack_type_use_block = false; + + return CMD_SUCCESS; +} + +DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd, + "no gprs control-ack-type-rach", NO_STR GPRS_TEXT + "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to " + "four access bursts format instead of default RLC/MAC control block\n") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gprs.mode == BTS_GPRS_NONE) { + vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); + return CMD_WARNING; + } + + bts->gprs.ctrl_ack_type_use_block = true; + + return CMD_SUCCESS; +} + DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd, "gprs network-control-order (nc0|nc1|nc2)", GPRS_TEXT @@ -4122,6 +4158,8 @@ install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd); install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd); install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd); + install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd); + install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd); install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd); install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd); install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd); diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c index cd7bfd5..1a5e435 100644 --- a/openbsc/src/libbsc/rest_octets.c +++ b/openbsc/src/libbsc/rest_octets.c @@ -618,8 +618,8 @@ bitvec_set_uint(bv, drx_timer_max, 3); /* ACCESS_BURST_TYPE: Hard-code 8bit */ bitvec_set_bit(bv, 0); - /* CONTROL_ACK_TYPE: Hard-code to RLC/MAC control block */ - bitvec_set_bit(bv, 1); + /* CONTROL_ACK_TYPE: */ + bitvec_set_bit(bv, gco->ctrl_ack_type_use_block); bitvec_set_uint(bv, gco->bs_cv_max, 4); if (0) { diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 69d2f7c..3f6d6b9 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -956,6 +956,7 @@ .t3192 = 1500, .drx_timer_max = 3, .bs_cv_max = 15, + .ctrl_ack_type_use_block = true, .ext_info_present = 0, .supports_egprs_11bit_rach = 0, .ext_info = { @@ -1003,6 +1004,9 @@ si13_default.no_pbcch.rac = bts->gprs.rac; si13_default.no_pbcch.net_ctrl_ord = bts->gprs.net_ctrl_ord; + si13_default.cell_opts.ctrl_ack_type_use_block = + bts->gprs.ctrl_ack_type_use_block; + /* Information about the other SIs */ si13_default.bcch_change_mark = bts->bcch_change_mark; si13_default.cell_opts.supports_egprs_11bit_rach = diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 9d794ee..75475db 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -315,6 +315,7 @@ bts->bsic = bsic; bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED; bts->dtxd = false; + bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */ bts->neigh_list_manual_mode = 0; bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */ bts->si_common.cell_sel_par.rxlev_acc_min = 0; -- To view, visit https://gerrit.osmocom.org/546 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie869ac0a82055110f1e3b875e246750c4e113336 Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:02:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:02:19 +0000 Subject: openbsc[master]: SNDCP: add SNDCP-XID encoder/decoder and unit test In-Reply-To: References: Message-ID: Patch Set 15: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/641 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e Gerrit-PatchSet: 15 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:02:24 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:02:24 +0000 Subject: openbsc[master]: RFC1144: add slhc code from linux kernel In-Reply-To: References: Message-ID: Patch Set 15: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/634 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied69c143678dc4a64cecc671f5c4dfebe19d8519 Gerrit-PatchSet: 15 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:02:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:02:42 +0000 Subject: openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Patch Set 17: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 17 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:05:55 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:05:55 +0000 Subject: openbsc[master]: V.42bis: add sourcecode from IAXmodem (SPANDSP) In-Reply-To: References: Message-ID: Patch Set 30: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/643 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iabedece9f97ca944a1e3f747bb073e532c4e9dca Gerrit-PatchSet: 30 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:08:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:08:54 +0000 Subject: openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Patch Set 36: Code-Review-1 (2 comments) https://gerrit.osmocom.org/#/c/644/36/openbsc/src/gprs/v42bis.c File openbsc/src/gprs/v42bis.c: Line 735 I think it is better to keep the original code as unmodified as possible, i.e. simply have #defines for this to do nothing, and to have a span_log macro to expand to DEBUGP. This way it will be easy to forward-port any updates/fixes in upstram spandsp if ever needed. https://gerrit.osmocom.org/#/c/644/36/openbsc/tests/v42bis/Makefile.am File openbsc/tests/v42bis/Makefile.am: Line 19: -lgtp -lrt -lm I think we should have a LIBGTP_LIBS or similar, rather than -lgtp. -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 36 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:15:04 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:15:04 +0000 Subject: openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Patch Set 3: Code-Review-1 (2 comments) https://gerrit.osmocom.org/#/c/803/3/openbsc/src/gprs/gprs_sndcp_dcomp.c File openbsc/src/gprs/gprs_sndcp_dcomp.c: Line 174: if (skip) { so if we have no compression configured, we still suffer the dynamic allocation of a new msgb and the memcpy. This is not good. If no compression is active, we should neither copy the msgb, nor have any memcpy. The same is true for both compression and decompression, and counts for header as well as payload compression. Please modify the patch accordingly. Line 338: if (!comp_entity) { I think -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:22:41 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:22:41 +0000 Subject: osmo-pcu[master]: Use qbit-TA to update Timing Advance In-Reply-To: References: Message-ID: Patch Set 9: Holger: It seems your comment were adressed, can you please re-check? -- To view, visit https://gerrit.osmocom.org/544 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I96fdbb20b09fb85fdd9fb6dcf3c25f6bee7f80e4 Gerrit-PatchSet: 9 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:26:56 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 10:26:56 +0000 Subject: osmo-pcu[master]: Handle Timing Advance IE properly In-Reply-To: References: Message-ID: Patch Set 6: Note: I also find 'wp' confusing but wanted to be consistent with the rest of the code. -- To view, visit https://gerrit.osmocom.org/552 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I786bf7fc999d401cc3d9e7f1e7a1fba953b5d458 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 10:58:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 17 Sep 2016 10:58:36 +0000 Subject: osmo-pcu[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 17 11:23:21 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 11:23:21 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#5). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 8 files changed, 75 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/5 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..a89d257 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = resp_msg->cb[0]; + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + msg->cb[0] = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..a7f0475 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ @@ -500,7 +500,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..7dd4f95 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -88,7 +90,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..bd0b6eb 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -288,6 +291,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -297,10 +301,13 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -327,9 +334,19 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0880ee9..26b1819 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, l1sap->u.tch.marker); } /* no message/data, we generate an empty traffic msg */ @@ -493,6 +493,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..47720d5 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -108,7 +110,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..4989b52 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -385,6 +388,7 @@ * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -394,10 +398,13 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -426,9 +433,19 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 17 11:25:37 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 11:25:37 +0000 Subject: osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Patch Set 4: (1 comment) https://gerrit.osmocom.org/#/c/691/4/src/osmo-bts-litecell15/l1_if.c File src/osmo-bts-litecell15/l1_if.c: Line 503: if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ > I think it might be more elegant to first handle the if (marker) send_onset I think it's more intuitive to place tail recursive call at the end of the function but I agree - it's more of stylistic question. -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Sep 17 12:15:42 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 12:15:42 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#6). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 8 files changed, 79 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/6 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..a89d257 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = resp_msg->cb[0]; + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + msg->cb[0] = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 21d047a..0779dac 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -503,7 +504,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index f01fdc2..88d71bf 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -90,7 +90,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 6ac2763..75b806e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -283,6 +286,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -293,10 +297,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -323,11 +330,21 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0bc6d14..f2ce932 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -496,6 +497,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 49b7e67..a90c39b 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 4ea95c5..9c49ea9 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -380,6 +383,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -390,10 +394,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -422,11 +429,21 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 17 12:23:51 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 12:23:51 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#7). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 8 files changed, 79 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/7 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..a89d257 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = resp_msg->cb[0]; + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + msg->cb[0] = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 21d047a..0779dac 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -503,7 +504,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index f01fdc2..88d71bf 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -90,7 +90,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 6ac2763..cbe7edc 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -283,6 +286,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -293,10 +297,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -323,11 +330,21 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 0bc6d14..f2ce932 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -496,6 +497,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 49b7e67..a90c39b 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 4ea95c5..2d86fca 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -380,6 +383,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -390,10 +394,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -422,11 +429,21 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 7 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 17 13:53:36 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 17 Sep 2016 13:53:36 +0000 Subject: [PATCH] osmo-bts[master]: lc15, sysmo: Use SID_FIRST_P1 to initiate DTX In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/692 to look at the new patch set (#2). lc15, sysmo: Use SID_FIRST_P1 to initiate DTX Some phone seems to not send SID_FIRST_P2 message which seems like a different understanding of the DTX spec. L1 accommodates for that by using P1 to supply data for SID. Hence we should use it to initiate DTX and ignore P2 message in case of AMR HR. Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 2 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/92/692/2 diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index cbe7edc..e06c4cf 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -462,8 +462,7 @@ case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; - case GsmL1_TchPlType_Amr_SidFirstP2: - /* L1 do not give us SID_FIRST data, just indication */ + case GsmL1_TchPlType_Amr_SidFirstP1: memcpy(sid_first, payload, payload_len); int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); if (len < 0) diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 2d86fca..b1ab086 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -565,8 +565,7 @@ case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; - case GsmL1_TchPlType_Amr_SidFirstP2: - /* L1 do not give us SID_FIRST data, just indication */ + case GsmL1_TchPlType_Amr_SidFirstP1: memcpy(sid_first, payload, payload_len); int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); if (len < 0) -- To view, visit https://gerrit.osmocom.org/692 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 02:09:57 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 02:09:57 +0000 Subject: [PATCH] openbsc[master]: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/853 to look at the new patch set (#2). utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 --- M openbsc/src/utils/Makefile.am 1 file changed, 0 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/53/853/2 diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 0dbb85c..7fcc4e3 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -8,7 +8,6 @@ -Wall \ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(SQLITE3_CFLAGS) \ -- To view, visit https://gerrit.osmocom.org/853 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 02:10:39 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 02:10:39 +0000 Subject: openbsc[master]: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 reinstate previous +2, only cosmetic modification due to rebase -- To view, visit https://gerrit.osmocom.org/853 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 02:11:43 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 02:11:43 +0000 Subject: osmo-pcu[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 should be in libosmocore/vty -- To view, visit https://gerrit.osmocom.org/753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 02:12:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 02:12:23 +0000 Subject: [MERGED] osmo-bts[master]: log causing rx event for lchan_lookup errors In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: log causing rx event for lchan_lookup errors ...................................................................... log causing rx event for lchan_lookup errors Add log_name to lchan_lookup() and pass such from the various RSL rx events that call it to validate the RSL chan_nr. Change-Id: I0d9923f47ac655b204169eec302d607412d5754d --- M src/common/rsl.c 1 file changed, 10 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/rsl.c b/src/common/rsl.c index 559599f..493ff3b 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -144,19 +144,21 @@ return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT); } -static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr) +static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, + const char *log_name) { int rc; struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc); if (!lchan) { - LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr); + LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n", log_name, + chan_nr); return NULL; } if (rc < 0) - LOGP(DRSL, LOGL_ERROR, "%s mismatching chan_nr=0x%02x\n", - gsm_ts_and_pchan_name(lchan->ts), chan_nr); + LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n", + gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr); return lchan; } @@ -2105,7 +2107,7 @@ } msg->l3h = (unsigned char *)rh + sizeof(*rh); - lchan = lchan_lookup(trx, rh->chan_nr); + lchan = lchan_lookup(trx, rh->chan_nr, "RSL rx RLL: "); if (!lchan) { LOGP(DRLL, LOGL_NOTICE, "Rx RLL %s for unknown lchan\n", rsl_msg_name(rh->c.msg_type)); @@ -2249,7 +2251,7 @@ } msg->l3h = (unsigned char *)cch + sizeof(*cch); - msg->lchan = lchan_lookup(trx, cch->chan_nr); + msg->lchan = lchan_lookup(trx, cch->chan_nr, "RSL rx CCHAN: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknown lchan\n", rsl_msg_name(cch->c.msg_type)); @@ -2303,7 +2305,7 @@ } msg->l3h = (unsigned char *)dch + sizeof(*dch); - msg->lchan = lchan_lookup(trx, dch->chan_nr); + msg->lchan = lchan_lookup(trx, dch->chan_nr, "RSL rx DCHAN: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknown lchan\n", rsl_or_ipac_msg_name(dch->c.msg_type)); @@ -2402,7 +2404,7 @@ } msg->l3h = (unsigned char *)dch + sizeof(*dch); - msg->lchan = lchan_lookup(trx, dch->chan_nr); + msg->lchan = lchan_lookup(trx, dch->chan_nr, "RSL rx IPACC: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknow lchan\n", rsl_msg_name(dch->c.msg_type)); -- To view, visit https://gerrit.osmocom.org/746 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0d9923f47ac655b204169eec302d607412d5754d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 02:27:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 02:27:47 +0000 Subject: openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Patch Set 36: (1 comment) https://gerrit.osmocom.org/#/c/644/36/openbsc/tests/v42bis/Makefile.am File openbsc/tests/v42bis/Makefile.am: Line 19: -lgtp -lrt -lm > I think we should have a LIBGTP_LIBS or similar, rather than -lgtp. yes, we do already have $(LIBGTP_LIBS) ready for use. -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 36 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Sep 19 06:11:07 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Mon, 19 Sep 2016 06:11:07 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 23: I have addressed all the comments raised. please let me know the status. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 23 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 06:43:56 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Mon, 19 Sep 2016 06:43:56 +0000 Subject: [PATCH] osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/819 to look at the new patch set (#4). Fix slot allocation based on direction configured Currently number of TS for second DL TBF is less compared to first DL TBF because PCU is considering the combined capacity during TS allocation. With this issue there was no fairness in throughput between the 2 DL TBFs This patch enables the user to maximize the number of TS allocation for the DL or UL TBF based on the direction configured through VTY with cfg_pcu_ts_alloc_maximise_cmd Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 6 files changed, 62 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/4 diff --git a/src/bts.h b/src/bts.h index ba6fc4d..d7a59ce 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,11 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum maximise_direction { + DL_ONLY, + UL_ONLY, + NO_MAXIMISE +}; struct BTS; struct GprsMs; @@ -191,6 +196,8 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + enum maximise_direction maximise_dir; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..8ccc270 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -775,9 +775,20 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) - continue; + switch (bts->maximise_dir) { + case UL_ONLY: + if (tx_window < max_ul_slots) + continue; + break; + case DL_ONLY: + if (rx_window < max_dl_slots) + continue; + break; + default: + if (capacity <= max_capacity) + continue; + break; + } max_capacity = capacity; max_ul_slots = tx_window; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..c476726 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->maximise_dir = NO_MAXIMISE; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..18cea07 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,35 @@ return CMD_SUCCESS; } +DEFUN(cfg_pcu_ts_alloc_maximise_type, + cfg_pcu_ts_alloc_maximise_cmd, + "maximise-direction (dl|ul)", + "number of TS allocation based on direction configured\n" + "maximise DL capacity\n" + "maximise UL capacity") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + if (!strcmp(argv[0], "dl")) + bts->maximise_dir = DL_ONLY; + else if (!strcmp(argv[0], "ul")) + bts->maximise_dir = UL_ONLY; + + return CMD_SUCCESS; +} + +DEFUN(cfg_pcu_no_maximise_direction, + cfg_pcu_no_maximise_direction_cmd, + "no maximise-direction", + NO_STR "Maximise direction configuration\n") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->maximise_dir = NO_MAXIMISE; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +1001,7 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_ts_alloc_maximise_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index f7794f7..0a97011 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->maximise_dir = NO_MAXIMISE; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -238,6 +240,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -285,6 +288,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[1].enable(); @@ -660,6 +664,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +703,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +812,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = DL_ONLY; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -830,13 +837,8 @@ if (dl_tbf2->pdch[i]) numTs2++; } - - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 == 4); tbf_free(dl_tbf1); tbf_free(dl_tbf2); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..9717411 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10795,4 +10795,4 @@ Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs TBF1: numTs(4) -TBF2: numTs(3) +TBF2: numTs(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Mon Sep 19 07:00:51 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 19 Sep 2016 07:00:51 +0000 Subject: osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 4: I am working on something else but the word "fairness" triggers me here. While you might be able to allocate more TS for the DL, you might end up not having a free one for the UL. How do you solve the "starvation" problem here? Starvation in the sense of always allocating the maximum and then not being able to allocate a USF/UL TS to receive an answer from the phone? What is the argument of making it configurable? Do we expect a lot of content producers trying to upload their podcast and want to have more UL than DL timeslots? -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:40 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:40 +0000 Subject: [MERGED] openbsc[master]: debug log for sms: fix/add In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: debug log for sms: fix/add ...................................................................... debug log for sms: fix/add One logged the wrong function name. Add others. Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 --- M openbsc/src/libmsc/gsm_04_11.c M openbsc/src/libmsc/sms_queue.c M openbsc/src/libmsc/vty_interface_layer3.c 3 files changed, 14 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index d1fdfb9..08d8fdf 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -888,7 +888,7 @@ return -EBUSY; } - DEBUGP(DLSMS, "send_sms_lchan()\n"); + DEBUGP(DLSMS, "%s()\n", __func__); /* FIXME: allocate transaction with message reference */ trans = trans_alloc(conn->bts->network, conn->subscr, @@ -996,10 +996,14 @@ * if yes, send the SMS this way */ conn = connection_for_subscr(subscr); if (conn) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS via already open connection %p to %s\n", + conn, subscr_name(subscr)); return gsm411_send_sms(conn, sms); } /* if not, we have to start paging */ + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n", + subscr_name(subscr)); res = subscr_request_channel(subscr, RSL_CHANNEED_SDCCH, paging_cb_send_sms, sms); if (!res) { diff --git a/openbsc/src/libmsc/sms_queue.c b/openbsc/src/libmsc/sms_queue.c index 5dbe81f..ebc53c2 100644 --- a/openbsc/src/libmsc/sms_queue.c +++ b/openbsc/src/libmsc/sms_queue.c @@ -225,10 +225,14 @@ sms = take_next_sms(smsq); - if (!sms) + if (!sms) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (%d attempted)\n", + attempted); break; + } rounds += 1; + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds); /* * This code needs to detect a loop. It assumes that no SMS @@ -243,6 +247,8 @@ first_sub = sms->receiver->id; initialized = 1; } else if (first_sub == sms->receiver->id) { + LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (loop) (%d attempted)\n", + attempted); sms_free(sms); break; } @@ -324,6 +330,7 @@ */ int sms_queue_trigger(struct gsm_sms_queue *smsq) { + LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n"); if (osmo_timer_pending(&smsq->push_queue)) return 0; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index fd3771a..6f0006c 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -176,6 +176,7 @@ sms_free(sms); return CMD_WARNING; } + LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n"); sms_free(sms); sms_queue_trigger(receiver->group->net->sms_queue); -- To view, visit https://gerrit.osmocom.org/856 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ied5d8e84d5d192c826bc131be8907eaa55190479 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:42 +0000 Subject: [MERGED] openbsc[master]: Sanity fixes for gsm0408_dispatch(): rc, assertions In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: Sanity fixes for gsm0408_dispatch(): rc, assertions ...................................................................... Sanity fixes for gsm0408_dispatch(): rc, assertions gsm0408_dispatch() is the main entry point for receiving data from the BSC/RNC level, so make sure callers pass valid pointers before using them all the way down the code path (related to CID#93769, a fix before this was refactored). For unknown/unimplemented packet discriminators, make sure to return error codes. Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 --- M openbsc/src/libmsc/gsm_04_08.c 1 file changed, 5 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 76217ae..08dac63 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -3664,6 +3664,9 @@ uint8_t pdisc = gsm48_hdr_pdisc(gh); int rc = 0; + OSMO_ASSERT(conn); + OSMO_ASSERT(msg); + LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message, pdisc=%d\n", pdisc); if (silent_call_reroute(conn, msg)) return silent_call_rx(conn, msg); @@ -3687,6 +3690,7 @@ case GSM48_PDISC_SM_GPRS: LOGP(DRLL, LOGL_NOTICE, "Unimplemented " "GSM 04.08 discriminator 0x%02x\n", pdisc); + rc = -ENOTSUP; break; case GSM48_PDISC_NC_SS: release_anchor(conn); @@ -3695,6 +3699,7 @@ default: LOGP(DRLL, LOGL_NOTICE, "Unknown " "GSM 04.08 discriminator 0x%02x\n", pdisc); + rc = -EINVAL; break; } -- To view, visit https://gerrit.osmocom.org/855 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ieec39c74a53ef4dfa971dd935c8c9aa60fef58c1 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:42 +0000 Subject: [MERGED] openbsc[master]: cosmetic: various comment, whitespace tweaks In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: cosmetic: various comment, whitespace tweaks ...................................................................... cosmetic: various comment, whitespace tweaks Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c M openbsc/src/libmsc/gsm_04_08.c M openbsc/tests/bsc/bsc_test.c 4 files changed, 4 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 939e0ee..9317717 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -103,7 +103,7 @@ uint8_t last_seen_nr; }; -/* the per subscriber data for lchan */ +/* active radio connection of a mobile subscriber */ struct gsm_subscriber_connection { struct llist_head entry; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index b8b5967..8c830a3 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -247,7 +247,6 @@ if (!conn) return NULL; - /* Configure the time and start it so it will be closed */ conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c30fbb0..76217ae 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1088,7 +1088,7 @@ if (subscr) { subscr_update(subscr, bts, - GSM_SUBSCRIBER_UPDATE_DETACHED); + GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr)); subscr->equipment.classmark1 = idi->classmark1; @@ -3657,7 +3657,7 @@ return 0; } -/* here we get data from the BSC level... */ +/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); diff --git a/openbsc/tests/bsc/bsc_test.c b/openbsc/tests/bsc/bsc_test.c index d032f61..cc45652 100644 --- a/openbsc/tests/bsc/bsc_test.c +++ b/openbsc/tests/bsc/bsc_test.c @@ -139,7 +139,7 @@ conn->bts = bts; conn->sccp_con = sccp_con; - /* start testinh with proper messages */ + /* start testing with proper messages */ printf("Testing BTS<->MSC message scan.\n"); for (i = 0; i < ARRAY_SIZE(test_scan_defs); ++i) { const struct test_definition *test_def = &test_scan_defs[i]; -- To view, visit https://gerrit.osmocom.org/854 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I131939cfba4d67d7e2c935341deeb14d09523fee Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:42 +0000 Subject: [MERGED] openbsc[master]: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS ...................................................................... utils/Makefile.am: remove unused LIBOSMOVTY_CFLAGS Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 --- M openbsc/src/utils/Makefile.am 1 file changed, 0 insertions(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am index 0dbb85c..7fcc4e3 100644 --- a/openbsc/src/utils/Makefile.am +++ b/openbsc/src/utils/Makefile.am @@ -8,7 +8,6 @@ -Wall \ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(SQLITE3_CFLAGS) \ -- To view, visit https://gerrit.osmocom.org/853 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id1152b105bb7364a06d9720829d39f587242b707 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:42 +0000 Subject: [MERGED] openbsc[master]: vty l3 help: fix typo 'comamnds'; fix english s/his// In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: vty l3 help: fix typo 'comamnds'; fix english s/his// ...................................................................... vty l3 help: fix typo 'comamnds'; fix english s/his// Change-Id: I6be52bbb69de8aa0a6d57a3a320661ad85fc2cc4 --- M openbsc/src/libmsc/vty_interface_layer3.c 1 file changed, 5 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index e7ff0a9..fd3771a 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -141,7 +141,7 @@ DEFUN(sms_send_pend, sms_send_pend_cmd, "sms send pending", - "SMS related comamnds\n" "SMS Sending related commands\n" + "SMS related commands\n" "SMS Sending related commands\n" "Send all pending SMS") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); @@ -199,10 +199,10 @@ } #define SUBSCR_TYPES "(extension|imsi|tmsi|id)" #define SUBSCR_HELP "Operations on a Subscriber\n" \ - "Identify subscriber by his extension (phone number)\n" \ - "Identify subscriber by his IMSI\n" \ - "Identify subscriber by his TMSI\n" \ - "Identify subscriber by his database ID\n" \ + "Identify subscriber by extension (phone number)\n" \ + "Identify subscriber by IMSI\n" \ + "Identify subscriber by TMSI\n" \ + "Identify subscriber by database ID\n" \ "Identifier for the subscriber\n" DEFUN(show_subscr, -- To view, visit https://gerrit.osmocom.org/852 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6be52bbb69de8aa0a6d57a3a320661ad85fc2cc4 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:43 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:43 +0000 Subject: [MERGED] openbsc[master]: remove unused bsc_copyright from bsc_vty.c In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: remove unused bsc_copyright from bsc_vty.c ...................................................................... remove unused bsc_copyright from bsc_vty.c Change-Id: I281791c0f57ca75ffe14431a3030811b2d224f0b --- M openbsc/src/libbsc/bsc_vty.c 1 file changed, 0 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index f856e30..5c95e85 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -4027,7 +4027,6 @@ } extern int bsc_vty_init_extra(void); -extern const char *openbsc_copyright; int bsc_vty_init(const struct log_info *cat) { -- To view, visit https://gerrit.osmocom.org/851 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I281791c0f57ca75ffe14431a3030811b2d224f0b Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:50:43 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:50:43 +0000 Subject: [MERGED] openbsc[master]: properly #include from gsm_subscriber.h In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: properly #include from gsm_subscriber.h ...................................................................... properly #include from gsm_subscriber.h Don't use quoted, local include, use <> style include. Cosmetic: also move stdbool.h include to the top to keep osmocom and openbsc includes grouped. Change-Id: Iaa3dc36768f96f6b8c91010a2ba389fdc37f1503 --- M openbsc/include/openbsc/gsm_subscriber.h 1 file changed, 3 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 3d7c244..314d619 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -1,11 +1,12 @@ #ifndef _GSM_SUBSCR_H #define _GSM_SUBSCR_H -#include "gsm_data.h" +#include + #include #include -#include +#include #define GSM_NAME_LENGTH 160 -- To view, visit https://gerrit.osmocom.org/850 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iaa3dc36768f96f6b8c91010a2ba389fdc37f1503 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 11:51:12 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 11:51:12 +0000 Subject: [MERGED] openbsc[master]: cosmetic: transaction.h: 1 comment typo, 1 whitespace In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: cosmetic: transaction.h: 1 comment typo, 1 whitespace ...................................................................... cosmetic: transaction.h: 1 comment typo, 1 whitespace Change-Id: Ia2629f9d9887b50b25c6996531b7ef518fb33335 --- M openbsc/include/openbsc/transaction.h 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index 6ef1612..9a87d04 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -14,7 +14,7 @@ /* Entry in list of all transactions */ struct llist_head entry; - /* Back pointer to the netweork struct */ + /* Back pointer to the network struct */ struct gsm_network *net; /* The protocol within which we live */ @@ -22,7 +22,7 @@ /* The current transaction ID */ uint8_t transaction_id; - + /* To whom we belong, unique identifier of remote MM entity */ struct gsm_subscriber *subscr; -- To view, visit https://gerrit.osmocom.org/791 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia2629f9d9887b50b25c6996531b7ef518fb33335 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 12:19:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 12:19:11 +0000 Subject: [PATCH] libosmocore[master]: remove unused function get_rate_ctr_group() Message-ID: Review at https://gerrit.osmocom.org/859 remove unused function get_rate_ctr_group() Unused after 22886d9e320ecf734d2827d825a191b977f70d2c "Fix retrieving rate_ctr over control interface" Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e --- M src/ctrl/control_if.c 1 file changed, 0 insertions(+), 37 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/59/859/1 diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 6d9a9fb..228fe35 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -448,43 +448,6 @@ return counters; } -static int get_rate_ctr_group(const char *ctr_group, int intv, struct ctrl_cmd *cmd) -{ - int i; - char *counters; - struct rate_ctr_group *ctrg; - - cmd->reply = talloc_asprintf(cmd, "All counters in group %s", ctr_group); - if (!cmd->reply) - goto oom; - - for (i=0;;i++) { - ctrg = rate_ctr_get_group_by_name_idx(ctr_group, i); - if (!ctrg) - break; - - counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); - if (!counters) - goto oom; - - cmd->reply = talloc_asprintf_append(cmd->reply, "%s", counters); - talloc_free(counters); - if (!cmd->reply) - goto oom; - } - - /* We found no counter group by that name */ - if (i == 0) { - cmd->reply = talloc_asprintf(cmd, "No counter group with name %s.", ctr_group); - return CTRL_CMD_ERROR; - } - - return CTRL_CMD_REPLY; -oom: - cmd->reply = "OOM."; - return CTRL_CMD_ERROR; -} - static int get_rate_ctr_group_idx(const struct rate_ctr_group *ctrg, int intv, struct ctrl_cmd *cmd) { char *counters; -- To view, visit https://gerrit.osmocom.org/859 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 12:19:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 19 Sep 2016 12:19:11 +0000 Subject: [PATCH] libosmocore[master]: remove unused local variable in get_rate_ctr() Message-ID: Review at https://gerrit.osmocom.org/860 remove unused local variable in get_rate_ctr() Unused after 22886d9e320ecf734d2827d825a191b977f70d2c "Fix retrieving rate_ctr over control interface" Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 --- M src/ctrl/control_if.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/60/860/1 diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 228fe35..05f6c76 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -474,7 +474,7 @@ { int intv; unsigned int idx; - char *ctr_group, *ctr_idx, *ctr_name, *tmp, *dup, *saveptr, *interval; + char *ctr_group, *ctr_idx, *tmp, *dup, *saveptr, *interval; struct rate_ctr_group *ctrg; const struct rate_ctr *ctr; -- To view, visit https://gerrit.osmocom.org/860 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:17:41 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 19 Sep 2016 14:17:41 +0000 Subject: [PATCH] osmo-pcu[master]: Use qbit-TA to update Timing Advance In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/544 to look at the new patch set (#10). Use qbit-TA to update Timing Advance Separate qbit-TA to TA conversion into separate function and use it for computing and updating Timing Advance. Note: the code was tested with TA=0 only to make sure it does not introduce regressions. Change-Id: I96fdbb20b09fb85fdd9fb6dcf3c25f6bee7f80e4 Fixes: OS#1531 --- M src/bts.cpp M src/bts.h M src/osmo-bts-litecell15/lc15_l1_if.c M src/osmo-bts-sysmo/sysmo_l1_if.c M src/pcu_l1_if.h 5 files changed, 46 insertions(+), 51 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/44/544/10 diff --git a/src/bts.cpp b/src/bts.cpp index 73ec1f7..521bcc4 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -478,8 +478,7 @@ int rc; int plen; uint8_t usf = 7; - uint8_t tsc; - uint16_t ta; + uint8_t tsc, ta = qta2ta(qta); uint16_t ms_class = 0; uint16_t priority = 0; @@ -489,13 +488,6 @@ "one:\n"); sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); - - if (qta < 0) - qta = 0; - if (qta > 252) - qta = 252; - - ta = qta >> 2; if (sb) { rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta); @@ -1480,6 +1472,23 @@ return rc; } +void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, + uint8_t ta) +{ + struct gprs_rlcmac_ul_tbf *tbf = + bts_main_data()->bts->ul_tbf_by_poll_fn(fn, trx_no, ts); + if (!tbf) + LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to " + "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n", + p, ta, trx_no, ts, fn); + else if (tbf->ta() != ta) { + LOGP(DL1IF, LOGL_INFO, "[%s] Updating TA %u -> %u on " + "TRX = %d, TS = %d, FN = %d\n", + p, tbf->ta(), ta, trx_no, ts, fn); + tbf->set_ta(ta); + } +} + gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi( LListHead *tbf_list, uint8_t tfi, enum gprs_rlcmac_tbf_direction dir) diff --git a/src/bts.h b/src/bts.h index ba6fc4d..8bea371 100644 --- a/src/bts.h +++ b/src/bts.h @@ -143,6 +143,15 @@ #endif }; +#ifdef __cplusplus +extern "C" { +#endif +void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, + uint8_t ta); +#ifdef __cplusplus +} +#endif + /** * This is the data from C. As soon as our minimal compiler is gcc 4.7 * we can start to compile pcu_vty.c with c++ and remove the split. diff --git a/src/osmo-bts-litecell15/lc15_l1_if.c b/src/osmo-bts-litecell15/lc15_l1_if.c index a6358ba..12a977b 100644 --- a/src/osmo-bts-litecell15/lc15_l1_if.c +++ b/src/osmo-bts-litecell15/lc15_l1_if.c @@ -32,6 +32,7 @@ #include #include #include +#include extern void *tall_pcu_ctx; @@ -204,6 +205,8 @@ data_ind->msgUnitParam.u8Size-1); get_meas(&meas, &data_ind->measParam); + bts_update_tbf_ta("PH-DATA", data_ind->u32Fn, fl1h->trx_no, + data_ind->u8Tn, qta2ta(meas.bto)); switch (data_ind->sapi) { case GsmL1_Sapi_Pdtch: @@ -235,31 +238,12 @@ static int handle_ph_ra_ind(struct lc15l1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind) { - uint8_t acc_delay; - if (ra_ind->measParam.fLinkQuality < MIN_QUAL_RACH) return 0; DEBUGP(DL1IF, "Rx PH-RA.ind"); - - /* check for under/overflow / sign */ - if (ra_ind->measParam.i16BurstTiming < 0) - acc_delay = 0; - else - acc_delay = ra_ind->measParam.i16BurstTiming >> 2; - - LOGP(DL1IF, LOGL_NOTICE, "got (P)RACH request, TA = %u (ignored)\n", - acc_delay); - -#warning "The (P)RACH request is just dropped here" - -#if 0 - if (acc_delay > bts->max_ta) { - LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", - acc_delay, btsb->max_ta); - return 0; - } -#endif + bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn, + qta2ta(ra_ind->measParam.i16BurstTiming)); return 0; } diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.c b/src/osmo-bts-sysmo/sysmo_l1_if.c index 75a2d5f..8994ac3 100644 --- a/src/osmo-bts-sysmo/sysmo_l1_if.c +++ b/src/osmo-bts-sysmo/sysmo_l1_if.c @@ -13,6 +13,7 @@ #include #include #include +#include extern void *tall_pcu_ctx; @@ -189,6 +190,8 @@ data_ind->msgUnitParam.u8Size-1); get_meas(&meas, &data_ind->measParam); + bts_update_tbf_ta("PH-DATA", data_ind->u32Fn, fl1h->trx_no, + data_ind->u8Tn, qta2ta(meas.bto)); switch (data_ind->sapi) { case GsmL1_Sapi_Pdtch: @@ -220,33 +223,14 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind) { - uint8_t acc_delay; - pcu_rx_ra_time(ra_ind->u16Arfcn, ra_ind->u32Fn, ra_ind->u8Tn); if (ra_ind->measParam.fLinkQuality < MIN_QUAL_RACH) return 0; DEBUGP(DL1IF, "Rx PH-RA.ind"); - - /* check for under/overflow / sign */ - if (ra_ind->measParam.i16BurstTiming < 0) - acc_delay = 0; - else - acc_delay = ra_ind->measParam.i16BurstTiming >> 2; - - LOGP(DL1IF, LOGL_NOTICE, "got (P)RACH request, TA = %u (ignored)\n", - acc_delay); - -#warning "The (P)RACH request is just dropped here" - -#if 0 - if (acc_delay > bts->max_ta) { - LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", - acc_delay, btsb->max_ta); - return 0; - } -#endif + bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn, + qta2ta(ra_ind->measParam.i16BurstTiming)); return 0; } diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h index b2a9832..d9d970d 100644 --- a/src/pcu_l1_if.h +++ b/src/pcu_l1_if.h @@ -33,6 +33,15 @@ } #endif +static inline uint8_t qta2ta(int16_t qta) +{ + if (qta < 0) + return 0; + if (qta > 252) + qta = 252; + return qta >> 2; +} + /* * L1 Measurement values */ -- To view, visit https://gerrit.osmocom.org/544 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I96fdbb20b09fb85fdd9fb6dcf3c25f6bee7f80e4 Gerrit-PatchSet: 10 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:18:17 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 14:18:17 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#29). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,457 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/29 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9a093ab..850eb42 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -19,7 +19,7 @@ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ - iu.h slhc.h + iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..4e15b9b --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 19496cb..2d70f5a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 245636b..2910c02 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,7 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 32920da..98084af 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -525,11 +547,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..a7877c1 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -143,6 +268,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +301,58 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +513,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +551,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +617,40 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + /* Apply header compression */ + rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + } +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +672,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +692,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +715,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +745,70 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } #if 0 @@ -619,3 +868,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..544ad52 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,280 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + uint8_t *data_o; + + /* Create a working copy of the incoming data */ + data_o = talloc_zero_size(NULL, len); + memcpy(data_o, data, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + memcpy(data, data_o, compr_len); + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + memcpy(data, data_o, compr_len); + } else + *pcomp_index = 0; + + talloc_free(data_o); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index be7637a..6e6bbfd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -314,7 +317,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 3e66978..1804280 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -33,6 +33,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 29 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:18:17 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 14:18:17 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/803 to look at the new patch set (#4). SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 594 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/03/803/4 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 9bea689..e21b485 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -20,7 +20,7 @@ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ iu.h slhc.h gprs_sndcp_comp.h gprs_sndcp_pcomp.h v42bis.h \ - v42bis_private.h + v42bis_private.h gprs_sndcp_dcomp.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..a76b4a4 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,53 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 2d70f5a..12d918e 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index f479d56..98abb3d 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -27,7 +27,8 @@ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ - slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c + slhc.c gprs_sndcp_comp.c gprs_sndcp_pcomp.c v42bis.c \ + gprs_sndcp_dcomp.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index a7877c1..197c4e7 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -314,13 +315,25 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -345,7 +358,8 @@ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, sne->nsapi, msg, npdu_len, expnd); - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) talloc_free(expnd); return rc; @@ -630,7 +644,8 @@ DEBUGP(DSNDCP, "===================================================\n"); debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { /* Apply header compression */ rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, @@ -638,6 +653,19 @@ if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + + /* Apply data compression */ + rc = gprs_sndcp_dcomp_compress(msg->data, msg->len, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); return -EIO; } @@ -774,13 +802,25 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -805,7 +845,8 @@ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, expnd); - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) talloc_free(expnd); return rc; @@ -876,8 +917,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -893,6 +937,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -1000,13 +1061,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->v42bis_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..7520546 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,357 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void v42bis_reset(v42bis_state_t *comp) +{ + /* This function performs a complete reset of the V.42bis compression + * state by reinitalizing the state withe the previously negotiated + * parameters. */ + + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + uint8_t *data_o; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Run compressor */ + data_o = talloc_zero_size(NULL, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_o; + compressed_data.buf_pointer = data_o; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + talloc_free(data_o); + return len; + } + + *pcomp_index = 1; + memcpy(data, data_o, compressed_data.len); + talloc_free(data_o); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int v42bis_expand_unitdata(uint8_t *data, unsigned int len, + uint8_t pcomp_index, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + int rc; + struct v42bis_output_buffer uncompressed_data; + uint8_t *data_i; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Decompress packet */ + data_i = talloc_zero_size(NULL, len); + memcpy(data_i, data, len); + uncompressed_data.buf = data; + uncompressed_data.buf_pointer = data; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + talloc_free(data_i); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = v42bis_expand_unitdata(data, len, pcomp_index, comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = v42bis_compress_unitdata(&pcomp_index, data, len, + comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 894ce84..f01798b 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -297,6 +297,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 4d4431e..48b99b2 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -36,6 +36,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:18:17 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 14:18:17 +0000 Subject: [PATCH] openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/644 to look at the new patch set (#37). V.42bis: integration and unit test - Edit previously committed V.42bis implementation to function outside IAXmodem. - Add unit test to verify the correct function of V.42bis Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h M openbsc/include/openbsc/v42bis.h M openbsc/include/openbsc/v42bis_private.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/v42bis.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/testsuite.at A openbsc/tests/v42bis/Makefile.am A openbsc/tests/v42bis/v42bis_test.c A openbsc/tests/v42bis/v42bis_test.ok 14 files changed, 1,135 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/44/644/37 -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 37 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:18:17 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 14:18:17 +0000 Subject: [PATCH] openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/635 to look at the new patch set (#18). RFC1144: integration and unit-test The previously pushed slhc implementation has been modified to compile and function outside of the kernel. Also debug log messages were added and datatypes ware matched. The implementation is now ready to be used Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h R openbsc/include/openbsc/slhc.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/slhc.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/slhc/Makefile.am A openbsc/tests/slhc/slhc_test.c A openbsc/tests/slhc/slhc_test.ok M openbsc/tests/testsuite.at 14 files changed, 544 insertions(+), 91 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/635/18 diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 8ce3b70..e75b9eb 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -83,6 +83,7 @@ tests/mm_auth/mm_auth_test tests/xid/xid_test tests/sndcp_xid/sndcp_xid_test +tests/slhc/slhc_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 9dc2f8d..cebabdc 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -232,6 +232,7 @@ tests/mm_auth/Makefile tests/xid/Makefile tests/sndcp_xid/Makefile + tests/slhc/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index a5ba3ef..9a093ab 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -19,7 +19,7 @@ gprs_gsup_client.h bsc_msg_filter.h \ oap.h oap_messages.h \ gtphub.h gprs_llc_xid.h gprs_sndcp.h gprs_sndcp_xid.h \ - iu.h + iu.h slhc.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 43ebb19..90ddca5 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -29,6 +29,7 @@ DBSSGP, DLLC, DSNDCP, + DSLHC, DNAT, DCTRL, DSMPP, diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc.h similarity index 97% rename from openbsc/include/openbsc/slhc_vj.h rename to openbsc/include/openbsc/slhc.h index 8716d59..cd5a47c 100644 --- a/openbsc/include/openbsc/slhc_vj.h +++ b/openbsc/include/openbsc/slhc.h @@ -171,7 +171,8 @@ #define NULLSLCOMPR (struct slcompress *)0 /* In slhc.c: */ -struct slcompress *slhc_init(int rslots, int tslots); +struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); + void slhc_free(struct slcompress *comp); int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, @@ -180,4 +181,7 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); int slhc_toss(struct slcompress *comp); +void slhc_i_status(struct slcompress *comp); +void slhc_o_status(struct slcompress *comp); + #endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index fa4a3dd..245636b 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -26,7 +26,8 @@ sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \ gprs_utils.c gprs_gsup_client.c \ sgsn_cdr.c sgsn_ares.c \ - oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c + oap.c oap_messages.c gprs_llc_xid.c gprs_sndcp_xid.c \ + slhc.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 52fc985..894ce84 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -292,6 +292,11 @@ .description = "SCCP User Adaptation (SUA)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DSLHC] = { + .name = "DSLHC", + .description = "RFC1144 TCP/IP Header compression (SLHC)", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c index 27ed252..cbdf8db 100644 --- a/openbsc/src/gprs/slhc.c +++ b/openbsc/src/gprs/slhc.c @@ -50,61 +50,77 @@ * driver code belonging close to PPP and SLIP */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef CONFIG_INET -/* Entire module is for IP only */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#define ERR_PTR(x) x + static unsigned char *encode(unsigned char *cp, unsigned short n); static long decode(unsigned char **cpp); static unsigned char * put16(unsigned char *cp, unsigned short x); static unsigned short pull16(unsigned char **cpp); +/* Replacement for kernel space function ip_fast_csum() */ +static uint16_t ip_fast_csum(uint8_t *iph, int ihl) +{ + int i; + uint16_t temp; + uint32_t accumulator = 0xFFFF; + + for(i=0;i0xFFFF) + { + accumulator++; + accumulator&=0xFFFF; + } + } + + return (uint16_t)(htons(~accumulator)&0xFFFF); +} + +/* Replacement for kernel space function put_unaligned() */ +static void put_unaligned(uint16_t val, void *ptr) +{ + memcpy(ptr,&val,sizeof(val)); +} + + /* Allocate compression data structure * slots must be in range 0 to 255 (zero meaning no compression) * Returns pointer to structure or ERR_PTR() on error. */ struct slcompress * -slhc_init(int rslots, int tslots) +slhc_init(const void *ctx, int rslots, int tslots) { register short i; register struct cstate *ts; struct slcompress *comp; if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) - return ERR_PTR(-EINVAL); + return NULL; - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = (struct slcompress *)talloc_zero_size(ctx,sizeof(struct slcompress)); if (! comp) goto out_fail; if (rslots > 0) { size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = kzalloc(rsize, GFP_KERNEL); + comp->rstate = (struct cstate *) talloc_zero_size(ctx, rsize); if (! comp->rstate) goto out_free; comp->rslot_limit = rslots - 1; @@ -112,7 +128,7 @@ if (tslots > 0) { size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = kzalloc(tsize, GFP_KERNEL); + comp->tstate = (struct cstate *) talloc_zero_size(ctx, tsize); if (! comp->tstate) goto out_free2; comp->tslot_limit = tslots - 1; @@ -141,11 +157,11 @@ return comp; out_free2: - kfree(comp->rstate); + talloc_free(comp->rstate); out_free: - kfree(comp); + talloc_free(comp); out_fail: - return ERR_PTR(-ENOMEM); + return NULL; } @@ -153,16 +169,18 @@ void slhc_free(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_free(): Freeing compression states...\n"); + if ( comp == NULLSLCOMPR ) return; if ( comp->tstate != NULLSLSTATE ) - kfree( comp->tstate ); + talloc_free(comp->tstate ); if ( comp->rstate != NULLSLSTATE ) - kfree( comp->rstate ); + talloc_free( comp->rstate ); - kfree( comp ); + talloc_free( comp ); } @@ -187,6 +205,8 @@ } else { *cp++ = n; } + + DEBUGP(DSLHC, "encode(): n=%04x\n",n); return cp; } @@ -256,6 +276,7 @@ comp->sls_o_nontcp++; else comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Not a TCP packat, will not touch...\n"); return isize; } /* Extract TCP header */ @@ -271,6 +292,7 @@ ! (th->ack)){ /* TCP connection stuff; send as regular IP */ comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Packet is part of a TCP connection, will not touch...\n"); return isize; } /* @@ -287,6 +309,9 @@ * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ + + DEBUGP(DSLHC, "slhc_compress(): Compressible packet detected!\n"); + for ( ; ; ) { if( ip->saddr == cs->cs_ip.saddr && ip->daddr == cs->cs_ip.daddr @@ -310,11 +335,14 @@ * state points to the newest and we only need to set * xmit_oldest to update the lru linkage. */ + + DEBUGP(DSLHC, "slhc_compress(): Header not yet seen, will memorize header for the next turn...\n"); comp->sls_o_misses++; comp->xmit_oldest = lcs->cs_this; goto uncompressed; found: + DEBUGP(DSLHC, "slhc_compress(): Header already seen, trying to compress...\n"); /* * Found it -- move to the front on the connection list. */ @@ -344,6 +372,39 @@ */ oth = &cs->cs_tcp; + /* Display a little more debug information about which of the + * header fields changed unexpectedly */ + if(ip->version != cs->cs_ip.version) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->version != cs->cs_ip.version\n"); + if(ip->ihl != cs->cs_ip.ihl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ihl != cs->cs_ip.ihl\n"); + if(ip->tos != cs->cs_ip.tos) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->tos != cs->cs_ip.tos\n"); + if((ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))\n"); + if(ip->ttl != cs->cs_ip.ttl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ttl != cs->cs_ip.ttl\n"); + if(th->doff != cs->cs_tcp.doff) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: th->doff != cs->cs_tcp.doff\n"); + if(ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): ip->ihl = %i\n", ip->ihl); + DEBUGP(DSLHC, "slhc_compress(): ip+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(ip+1),((ip->ihl)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: cs->cs_ipopt = %s\n", + osmo_hexdump_nospc((uint8_t*)(cs->cs_ipopt),((ip->ihl)-5)*4)); + } + if(th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): th->doff = %i\n", th->doff); + DEBUGP(DSLHC, "slhc_compress(): th+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(th+1),((th->doff)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): cs->cs_tcpopt = %s\n", + osmo_hexdump_nospc((uint8_t*)cs->cs_tcpopt, + ((th->doff)-5)*4)); + } + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl || ip->tos != cs->cs_ip.tos || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) @@ -351,6 +412,7 @@ || th->doff != cs->cs_tcp.doff || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + DEBUGP(DSLHC, "slhc_compress(): The header contains unexpected changes, can't compress...\n"); goto uncompressed; } @@ -362,6 +424,7 @@ */ if(th->urg){ deltaS = ntohs(th->urg_ptr); + DEBUGP(DSLHC, "slhc_compress(): flag: Urgent Pointer (U) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_U; } else if(th->urg_ptr != oth->urg_ptr){ @@ -369,21 +432,29 @@ * implementation should never do this but RFC793 * doesn't prohibit the change so we have to deal * with it. */ + DEBUGP(DSLHC, "slhc_compress(): URG not set but urp changed, can't compress...\n"); goto uncompressed; } if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Window (W) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_W; } if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ - if(deltaA > 0x0000ffff) + if(deltaA > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Ack (A) = 1\n"); cp = encode(cp,deltaA); changes |= NEW_A; } if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ - if(deltaS > 0x0000ffff) + if(deltaS > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_S; } @@ -399,17 +470,21 @@ if(ip->tot_len != cs->cs_ip.tot_len && ntohs(cs->cs_ip.tot_len) == hlen) break; + DEBUGP(DSLHC, "slhc_compress(): Retransmitted packet detected, can't compress...\n"); goto uncompressed; case SPECIAL_I: case SPECIAL_D: /* actual changes match one of our special case encodings -- * send packet uncompressed. */ + DEBUGP(DSLHC, "slhc_compress(): Special case detected, can't compress...\n"); goto uncompressed; case NEW_S|NEW_A: if(deltaS == deltaA && deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_compress(): Special case for echoed terminal traffic detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_I; cp = new_seq; } @@ -417,6 +492,8 @@ case NEW_S: if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for data xfer */ + DEBUGP(DSLHC, "slhc_compress(): Special case for data xfer detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Ack (A) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_D; cp = new_seq; } @@ -424,11 +501,14 @@ } deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); if(deltaS != 1){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta IP ID (I) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_I; } - if(th->psh) + if(th->psh) { + DEBUGP(DSLHC, "slhc_compress(): flag: Push (P) = 1\n"); changes |= TCP_PUSH_BIT; + } /* Grab the cksum before we overwrite it below. Then update our * state with this packet's header. */ @@ -445,6 +525,7 @@ if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ cp = ocp; *cpp = ocp; + DEBUGP(DSLHC, "slhc_compress(): flag: Connection number (C) = 1\n"); *cp++ = changes | NEW_C; *cp++ = cs->cs_this; comp->xmit_current = cs->cs_this; @@ -456,6 +537,10 @@ *(__sum16 *)cp = csum; cp += 2; /* deltaS is now the size of the change section of the compressed header */ + + DEBUGP(DSLHC, "slhc_compress(): Delta-list length (deltaS) = %li\n",deltaS); + DEBUGP(DSLHC, "slhc_compress(): Original header len (hlen) = %i\n",hlen); + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ memcpy(cp+deltaS,icp+hlen,isize-hlen); comp->sls_o_compressed++; @@ -467,6 +552,7 @@ * to use on future compressed packets in the protocol field). */ uncompressed: + DEBUGP(DSLHC, "slhc_compress(): Packet will be sent uncompressed...\n"); memcpy(&cs->cs_ip,ip,20); memcpy(&cs->cs_tcp,th,20); if (ip->ihl > 5) @@ -538,6 +624,8 @@ switch(changes & SPECIALS_MASK){ case SPECIAL_I: /* Echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_uncompress(): Echoed terminal traffic detected\n"); + { register short i; i = ntohs(ip->tot_len) - hdrlen; @@ -547,11 +635,13 @@ break; case SPECIAL_D: /* Unidirectional data */ + DEBUGP(DSLHC, "slhc_uncompress(): Unidirectional data detected\n"); thp->seq = htonl( ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen); break; default: + DEBUGP(DSLHC, "slhc_uncompress(): default packet type detected\n"); if(changes & NEW_U){ thp->urg = 1; if((x = decode(&cp)) == -1) { @@ -601,6 +691,7 @@ ip->tot_len = htons(len); ip->check = 0; + DEBUGP(DSLHC, "slhc_uncompress(): making space for the reconstructed header...\n"); memmove(icp + hdrlen, cp, len - hdrlen); cp = icp; @@ -625,6 +716,7 @@ return len; bad: + DEBUGP(DSLHC, "slhc_uncompress(): bad packet detected!\n"); comp->sls_i_error++; return slhc_toss( comp ); } @@ -641,6 +733,7 @@ if(isize < 20) { /* The packet is shorter than a legal IP header */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The packet is shorter than a legal IP header ==> slhc_toss()\n"); return slhc_toss( comp ); } /* Peek at the IP header's IHL field to find its length */ @@ -648,6 +741,7 @@ if(ihl < 20 / 4){ /* The IP header length field is too small */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The IP header length field is too small ==> slhc_toss()\n"); return slhc_toss( comp ); } index = icp[9]; @@ -656,10 +750,12 @@ if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; + DEBUGP(DSLHC, "slhc_remember(): Bad IP header checksum; discard ==> slhc_toss()\n"); return slhc_toss( comp ); } if(index > comp->rslot_limit) { comp->sls_i_error++; + DEBUGP(DSLHC, "slhc_remember(): index > comp->rslot_limit ==> slhc_toss()\n"); return slhc_toss(comp); } @@ -683,6 +779,7 @@ int slhc_toss(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_toss(): Reset compression state...\n"); if ( comp == NULLSLCOMPR ) return 0; @@ -690,55 +787,27 @@ return 0; } -#else /* CONFIG_INET */ - -int -slhc_toss(struct slcompress *comp) +void slhc_i_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); - return -EINVAL; -} -int -slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); - return -EINVAL; -} -int -slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_i_status(): %d Cmp, %d Uncmp, %d Bad, %d Tossed\n", + comp->sls_i_compressed, + comp->sls_i_uncompressed, + comp->sls_i_error, + comp->sls_i_tossed); + } } -int -slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +void slhc_o_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_o_status(): %d Cmp, %d Uncmp, %d AsIs, %d NotTCP %d Searches, %d Misses\n", + comp->sls_o_compressed, + comp->sls_o_uncompressed, + comp->sls_o_tcp, + comp->sls_o_nontcp, + comp->sls_o_searches, + comp->sls_o_misses); + } } -void -slhc_free(struct slcompress *comp) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); -} -struct slcompress * -slhc_init(int rslots, int tslots) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); - return NULL; -} - -#endif /* CONFIG_INET */ - -/* VJ header compression */ -EXPORT_SYMBOL(slhc_init); -EXPORT_SYMBOL(slhc_free); -EXPORT_SYMBOL(slhc_remember); -EXPORT_SYMBOL(slhc_compress); -EXPORT_SYMBOL(slhc_uncompress); -EXPORT_SYMBOL(slhc_toss); - -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 1debb2d..d5aa356 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid +SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau subscr mm_auth xid sndcp_xid slhc if BUILD_NAT SUBDIRS += bsc-nat bsc-nat-trie diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 45d1780..3e66978 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -32,6 +32,7 @@ $(top_builddir)/src/gprs/oap_messages.o \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(top_builddir)/src/gprs/slhc.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ diff --git a/openbsc/tests/slhc/Makefile.am b/openbsc/tests/slhc/Makefile.am new file mode 100644 index 0000000..32a3cc4 --- /dev/null +++ b/openbsc/tests/slhc/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = slhc_test.ok + +noinst_PROGRAMS = slhc_test + +slhc_test_SOURCES = slhc_test.c + +slhc_test_LDADD = \ + $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) + + diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c new file mode 100644 index 0000000..59a5425 --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.c @@ -0,0 +1,298 @@ +/* Test SLHC/RFC1144 TCP/IP Header compression/decompression */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +/* Number of compression slots (S0-1) */ +#define SLOTS 8 + +/* Maximum packet bytes to display */ +#define DISP_MAX_BYTES 100 + +/* Sample packets to test with */ +#define PACKETS_LEN 6 +char *packets[] = { + "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", + "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", + "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", + "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" +}; + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int compress(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + uint8_t *comp_ptr; /* Not used */ + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int expand(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + int data_decompressed_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Handle an uncompressed packet (learn header information */ + if ((data_i[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Calculate IP Header checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Check TCP/IP packet */ +static void check_packet(const void *ctx, uint8_t *packet, int len) +{ + /* Check IP header */ + OSMO_ASSERT(len > 20); + OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + + /* Check TCP packet */ + if (packet[9] != 0x06) + return; + OSMO_ASSERT(len > 40); + OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); +} + +/* Strip TCP options from TCP/IP packet */ +static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) +{ + uint8_t doff; + uint16_t csum; + + /* Check if the packet can be handled here */ + if (len < 37) + return len; + if (packet[9] != 0x06) + return len; + + /* Strip TCP/IP options from packet */ + doff = ((packet[32] >> 4) & 0x0F) * 4; + memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); + len = len - (doff - 20); + + /* Repair data offset (TCP header length) */ + packet[32] &= 0x0F; + packet[32] |= 0x50; + + /* Repair checksum */ + packet[36] = 0; + packet[37] = 0; + csum = calc_tcpip_csum(ctx, packet, len); + packet[36] = csum & 0xFF; + packet[37] = csum >> 8 & 0xFF; + + /* Repair total length */ + packet[3] = len & 0xFF; + packet[2] = len >> 8 & 0xFF; + + /* Repair IP header checksum */ + packet[10] = 0; + packet[11] = 0; + csum = calc_ip_csum(packet, 20); + packet[10] = csum & 0xFF; + packet[11] = csum >> 8 & 0xFF; + printf("csum=%04x\n", csum); + + return len; +} + +/* Compress / Decompress packets */ +static void test_slhc(const void *ctx) +{ + char packet_ascii[2048]; + int i; + + struct slcompress *comp; + uint8_t packet[1024]; + int packet_len; + uint8_t packet_compr[1024]; + int packet_compr_len; + uint8_t packet_decompr[1024]; + int packet_decompr_len; + + printf("Allocating compression state...\n"); + comp = slhc_init(ctx, SLOTS, SLOTS); + OSMO_ASSERT(comp); + + for(i=0;i DISP_MAX_BYTES) + packet_compr_len = DISP_MAX_BYTES; + if (packet_len > DISP_MAX_BYTES) + packet_len = DISP_MAX_BYTES; + if (packet_decompr_len > DISP_MAX_BYTES) + packet_decompr_len = DISP_MAX_BYTES; + printf("Original Packet: (%i bytes) %s\n", packet_len, + osmo_hexdump_nospc(packet, packet_len)); + printf("DecompressedPacket: (%i bytes) %s\n", + packet_decompr_len, osmo_hexdump_nospc(packet_decompr, + packet_decompr_len)); + printf("CompressedPacket: (%i bytes) %s\n", packet_compr_len, + osmo_hexdump_nospc(packet_compr, packet_compr_len)); + slhc_o_status(comp); + slhc_o_status(comp); + + printf("\n"); + } + + printf("Freeing compression state...\n"); + slhc_free(comp); + printf("\n"); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + }, + [DSLHC] = { + .name = "DSLHC", + .description = + "Van Jacobson RFC1144 TCP/IP header compression (SLHC)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *ctx; + + osmo_init_logging(&info); + + ctx = talloc_named_const(NULL, 0, "slhc_ctx"); + + test_slhc(ctx); + + printf("Done\n"); + + talloc_report_full(ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/slhc/slhc_test.ok b/openbsc/tests/slhc/slhc_test.ok new file mode 100644 index 0000000..636241d --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.ok @@ -0,0 +1,52 @@ +Allocating compression state... +csum=b3a9 +Compressing... +Decompressing... +Results: +Original Packet: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +DecompressedPacket: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +CompressedPacket: (52 bytes) 7510003446dd40004000a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 + +csum=97a9 +Compressing... +Decompressing... +Results: +Original Packet: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +DecompressedPacket: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +CompressedPacket: (43 bytes) df00cda4fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 + +csum=baa9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +DecompressedPacket: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +CompressedPacket: (9 bytes) dc00a70a5227fffd01 + +csum=b9a9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +DecompressedPacket: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +CompressedPacket: (7 bytes) db00a706fffb01 + +csum=7ba9 +Compressing... +Decompressing... +Results: +Original Packet: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +DecompressedPacket: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +CompressedPacket: (68 bytes) db00c2d00d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a + +csum=aca9 +Compressing... +Decompressing... +Results: +Original Packet: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +DecompressedPacket: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +CompressedPacket: (18 bytes) df0021fb706f6c6c7578206c6f67696e3a20 + +Freeing compression state... + +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 85a81d6..5f37b8e 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -136,3 +136,8 @@ AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([slhc]) +AT_KEYWORDS([slhc]) +cat $abs_srcdir/slhc/slhc_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 18 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:32:26 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 19 Sep 2016 14:32:26 +0000 Subject: libosmocore[master]: remove unused function get_rate_ctr_group() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/859 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 14:33:10 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 19 Sep 2016 14:33:10 +0000 Subject: libosmocore[master]: remove unused local variable in get_rate_ctr() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/860 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:00:44 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add SNDCP-XID encoder/decoder and unit test In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/641 to look at the new patch set (#16). SNDCP: add SNDCP-XID encoder/decoder and unit test The SNDCP-XID (or layer-3 xid) is used to exchange layer-3 parameters such as compression. The encoder encodes a bytestream that is then sent as regular XID field from LLC. We will need the SNDCP-XID to negotiate the parameters for our upcomming GPRS data and header compression features Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_xid.h M openbsc/src/gprs/Makefile.am A openbsc/src/gprs/gprs_sndcp_xid.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/sndcp_xid/Makefile.am A openbsc/tests/sndcp_xid/sndcp_xid_test.c A openbsc/tests/sndcp_xid/sndcp_xid_test.ok M openbsc/tests/testsuite.at 12 files changed, 2,350 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/41/641/16 diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 518a960..8ce3b70 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -82,6 +82,7 @@ tests/gtphub/gtphub_test tests/mm_auth/mm_auth_test tests/xid/xid_test +tests/sndcp_xid/sndcp_xid_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index f63d61f..9dc2f8d 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -231,6 +231,7 @@ tests/gtphub/Makefile tests/mm_auth/Makefile tests/xid/Makefile + tests/sndcp_xid/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index cae8ba4..a91322f 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,7 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ gsm_04_11.h \ diff --git a/openbsc/include/openbsc/gprs_sndcp_xid.h b/openbsc/include/openbsc/gprs_sndcp_xid.h new file mode 100644 index 0000000..02904a7 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_xid.h @@ -0,0 +1,216 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include + +#define CURRENT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ +#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit + * for compression enitity number */ + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ +#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ + +/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control + * information compression field (Figure 7) and 3GPP TS 44.065, + * 6.6.1.1 Format of the data compression field (Figure 9) */ +struct gprs_sndcp_comp_field { + struct llist_head list; + + /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ + unsigned int p; + + /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int entity; + + /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ + int algo; + + /* Number of contained PCOMP / DCOMP values */ + uint8_t comp_len; + + /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ + uint8_t comp[MAX_COMP]; + + /* Note: Only one of the following struct pointers may, + be used. Unused pointers must be set to NULL! */ + struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; + struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; + struct gprs_sndcp_pcomp_rohc_params *rohc_params; + struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; + struct gprs_sndcp_dcomp_v44_params *v44_params; +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_hdr_comp_algo { + RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ + RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ + ROHC /* Robust Header Compression, see also 6.5.4 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_data_comp_algo { + V42BIS, /* V.42bis data compression, see also 6.6.2 */ + V44 /* V44 data compression, see also: 6.6.3 */ +}; + +/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ +enum gprs_sndcp_xid_param_types { + SNDCP_XID_VERSION_NUMBER, + SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ + SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ +struct gprs_sndcp_pcomp_rfc1144_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int s01; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ +enum gprs_sndcp_pcomp_rfc1144_pcomp { + RFC1144_PCOMP1, /* Uncompressed TCP */ + RFC1144_PCOMP2, /* Compressed TCP */ + RFC1144_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ +struct gprs_sndcp_pcomp_rfc2507_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int f_max_period; /* (default 256) */ + int f_max_time; /* (default 5) */ + int max_header; /* (default 168) */ + int tcp_space; /* (default 15) */ + int non_tcp_space; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ +enum gprs_sndcp_pcomp_rfc2507_pcomp { + RFC2507_PCOMP1, /* Full Header */ + RFC2507_PCOMP2, /* Compressed TCP */ + RFC2507_PCOMP3, /* Compressed TCP non delta */ + RFC2507_PCOMP4, /* Compressed non TCP */ + RFC2507_PCOMP5, /* Context state */ + RFC2507_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ +struct gprs_sndcp_pcomp_rohc_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int max_cid; /* (default 15) */ + int max_header; /* (default 168) */ + uint8_t profile_len; /* (default 1) */ + uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ +enum gprs_sndcp_pcomp_rohc_pcomp { + ROHC_PCOMP1, /* ROHC small CIDs */ + ROHC_PCOMP2, /* ROHC large CIDs */ + ROHC_PCOMP_NUM /* Number of pcomp values */ +}; + +/* ROHC compression profiles, see also: + http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ +enum gprs_sndcp_xid_rohc_profiles { + ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ + ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ + ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ + ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ + ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ + ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ + ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ + ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ + ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ + ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ + ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ + ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ + ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ + ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ + ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ + ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ +}; + +/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ +struct gprs_sndcp_dcomp_v42bis_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int p0; /* (default 3) */ + int p1; /* (default 2048) */ + int p2; /* (default 20) */ + +}; + +/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v42bis_dcomp { + V42BIS_DCOMP1, /* V.42bis enabled */ + V42BIS_DCOMP_NUM /* Number of dcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ +struct gprs_sndcp_dcomp_v44_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int c0; /* (default 10000000) */ + int p0; /* (default 3) */ + int p1t; /* Refer to subclause 6.6.3.1.4 */ + int p1r; /* Refer to subclause 6.6.3.1.5 */ + int p3t; /* (default 3 x p1t) */ + int p3r; /* (default 3 x p1r) */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v44_dcomp { + V44_DCOMP1, /* Packet method compressed */ + V44_DCOMP2, /* Multi packet method compressed */ + V44_DCOMP_NUM /* Number of dcomp values */ +}; + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields); + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t * src, + unsigned int src_len, + const struct llist_head *comp_fields_req); + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class( + const struct gprs_sndcp_comp_field *comp_field); + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl); + diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 59136bd..3b58399 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -72,6 +72,7 @@ gprs_sgsn.c \ gprs_sndcp.c \ gprs_sndcp_vty.c \ + gprs_sndcp_xid.c \ sgsn_main.c \ sgsn_vty.c \ sgsn_libgtp.c \ @@ -98,6 +99,7 @@ $(LIBCRYPTO_LIBS) \ -lrt \ -lgtp \ + -lm \ $(NULL) if BUILD_IU osmo_sgsn_LDADD += \ diff --git a/openbsc/src/gprs/gprs_sndcp_xid.c b/openbsc/src/gprs/gprs_sndcp_xid.c new file mode 100644 index 0000000..270bdee --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_xid.c @@ -0,0 +1,1803 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* When the propose bit in an SNDCP-XID compression field is set to zero, + * the algorithm identifier is stripped. The algoritm parameters are specific + * for each algorithms. The following struct is used to pass the information + * about the referenced algorithm to the parser. */ +struct entity_algo_table { + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */ + unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or + SNDCP_XID_PROTOCOL_COMPRESSION */ +}; + +/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */ + +/* Encode applicable sapis (works the same in all three compression schemes) */ +static int encode_pcomp_applicable_sapis(uint8_t *dst, + const uint8_t *nsapis, + uint8_t nsapis_len) +{ + /* NOTE: Buffer *dst needs offer at 2 bytes + * of space to store the generation results */ + + uint16_t blob; + uint8_t nsapi; + int i; + + /* Bail if number of possible nsapis exceeds valid range + * (Only 11 nsapis possible for PDP-Contexts) */ + OSMO_ASSERT(nsapis_len <= 11); + + /* Encode applicable SAPIs */ + blob = 0; + for (i = 0; i < nsapis_len; i++) { + nsapi = nsapis[i]; + /* Only NSAPI 5 to 15 are applicable for user traffic (PDP- + * contexts). Only for these NSAPIs SNDCP-XID parameters + * can apply. See also 3GPP TS 44.065, 5.1 Service primitives */ + OSMO_ASSERT(nsapi >= 5 && nsapi <= 15); + blob |= (1 << nsapi); + } + + /* Store result */ + *dst = (blob >> 8) & 0xFF; + dst++; + *dst = blob & 0xFF; + + return 2; +} + +/* Encode rfc1144 parameter field + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int encode_pcomp_rfc1144_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc1144_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 3); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode s01 (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + OSMO_ASSERT(params->s01 >= 0); + OSMO_ASSERT(params->s01 <= 255); + *dst = params->s01; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* + * Encode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) + */ +static int encode_pcomp_rfc2507_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc2507_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 9); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_period >= 1); + OSMO_ASSERT(params->f_max_period <= 65535); + *dst = (params->f_max_period >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->f_max_period) & 0xFF; + dst++; + dst_counter++; + + /* Encode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_time >= 1); + OSMO_ASSERT(params->f_max_time <= 255); + *dst = params->f_max_time; + dst++; + dst_counter++; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = params->max_header; + dst++; + dst_counter++; + + /* Encode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->tcp_space >= 3); + OSMO_ASSERT(params->tcp_space <= 255); + *dst = params->tcp_space; + dst++; + dst_counter++; + + /* Encode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->non_tcp_space >= 3); + OSMO_ASSERT(params->non_tcp_space <= 65535); + *dst = (params->non_tcp_space >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->non_tcp_space) & 0xFF; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode ROHC parameter field + * (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int encode_pcomp_rohc_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_pcomp_rohc_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 36 + * (2 * 16 Profiles + 2 * 3 Parameter) bytes + * of memory space to store generation results */ + + int i; + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 38); + + /* Bail if number of ROHC profiles exceeds limit + * (ROHC supports only a maximum of 16 different profiles) */ + OSMO_ASSERT(params->profile_len >= 0); + OSMO_ASSERT(params->profile_len <= 16); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_cid >= 0); + OSMO_ASSERT(params->max_cid <= 16383); + *dst = (params->max_cid >> 8) & 0xFF; + dst++; + *dst = params->max_cid & 0xFF; + dst++; + dst_counter += 2; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = (params->max_header >> 8) & 0xFF; + dst++; + *dst = params->max_header & 0xFF; + dst++; + dst_counter += 2; + + /* Encode ROHC Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < params->profile_len; i++) { + *dst = (params->profile[i] >> 8) & 0xFF; + dst++; + *dst = params->profile[i] & 0xFF; + dst++; + dst_counter += 2; + } + + /* Return generated length */ + return dst_counter; +} + +/* Encode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int encode_dcomp_v42bis_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_dcomp_v42bis_params *params) +{ + /* NOTE: Buffer *dst should offer at least 6 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 6); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p1 >= 512); + OSMO_ASSERT(params->p1 <= 65535); + *dst = (params->p1 >> 8) & 0xFF; + dst++; + *dst = params->p1 & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p2 >= 6); + OSMO_ASSERT(params->p2 <= 250); + *dst = params->p2; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode V44 parameter field + * (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int encode_dcomp_v44_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_dcomp_v44_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 12 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 12); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->c0 == 0x80 || params->c0 == 0xC0); + *dst = params->c0 & 0xC0; + dst++; + dst_counter++; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1t >= 256); + OSMO_ASSERT(params->p1t <= 65535); + *dst = (params->p1t >> 8) & 0xFF; + dst++; + *dst = params->p1t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1r >= 256); + OSMO_ASSERT(params->p1r <= 65535); + *dst = (params->p1r >> 8) & 0xFF; + dst++; + *dst = params->p1r & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3t >= 0); + OSMO_ASSERT(params->p3t <= 65535); + OSMO_ASSERT(params->p3t >= 2 * params->p1t); + *dst = (params->p3t >> 8) & 0xFF; + dst++; + *dst = params->p3t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3r >= 0); + OSMO_ASSERT(params->p3r <= 65535); + OSMO_ASSERT(params->p3r >= 2 * params->p1r); + *dst = (params->p3r >> 8) & 0xFF; + dst++; + *dst = params->p3r & 0xFF; + dst++; + dst_counter += 2; + + /* Return generated length */ + return dst_counter; +} + +/* Encode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_comp_field *comp_field) +{ + int dst_counter = 0; + int len; + int expected_length; + int i; + + uint8_t payload_bytes[256]; + int payload_bytes_len = -1; + + /* If possible, try do encode payload bytes first */ + if (comp_field->rfc1144_params) { + payload_bytes_len = + encode_pcomp_rfc1144_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc1144_params); + } else if (comp_field->rfc2507_params) { + payload_bytes_len = + encode_pcomp_rfc2507_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc2507_params); + } else if (comp_field->rohc_params) { + payload_bytes_len = + encode_pcomp_rohc_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rohc_params); + } else if (comp_field->v42bis_params) { + payload_bytes_len = + encode_dcomp_v42bis_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v42bis_params); + } else if (comp_field->v44_params) { + payload_bytes_len = + encode_dcomp_v44_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v44_params); + } else + OSMO_ASSERT(false); + + /* Bail immediately if payload byte generation failed */ + OSMO_ASSERT(payload_bytes_len >= 0); + + /* Bail if comp_len is out of bounds */ + OSMO_ASSERT(comp_field->comp_len <= sizeof(comp_field->comp)); + + /* Calculate length field of the data block */ + if (comp_field->p) { + len = + payload_bytes_len + + ceil((double)(comp_field->comp_len) / 2.0); + expected_length = len + 3; + } else { + len = payload_bytes_len; + expected_length = len + 2; + } + + /* Bail immediately if no sufficient memory space is supplied */ + OSMO_ASSERT(dst_maxlen >= expected_length); + + /* Check if the entity number is within bounds */ + OSMO_ASSERT(comp_field->entity <= 0x1f); + + /* Check if the algorithm number is within bounds */ + OSMO_ASSERT(comp_field->algo >= 0 || comp_field->algo <= 0x1f); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode Propose bit */ + if (comp_field->p) + *dst |= (1 << 7); + + /* Encode entity number */ + *dst |= comp_field->entity & 0x1F; + dst++; + dst_counter++; + + /* Encode algorithm number */ + if (comp_field->p) { + *dst |= comp_field->algo & 0x1F; + dst++; + dst_counter++; + } + + /* Encode length field */ + *dst |= len & 0xFF; + dst++; + dst_counter++; + + /* Encode PCOMP/DCOMP values */ + if (comp_field->p) { + for (i = 0; i < comp_field->comp_len; i++) { + /* Check if submitted PCOMP/DCOMP + values are within bounds */ + if ((comp_field->comp[i] < 0) + || (comp_field->comp[i] > 0x0F)) + return -EINVAL; + + if (i & 1) { + *dst |= comp_field->comp[i] & 0x0F; + dst++; + dst_counter++; + } else + *dst |= (comp_field->comp[i] << 4) & 0xF0; + } + + if (i & 1) { + dst++; + dst_counter++; + } + } + + /* Append payload bytes */ + memcpy(dst, payload_bytes, payload_bytes_len); + dst_counter += payload_bytes_len; + + /* Return generated length */ + return dst_counter; +} + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field + *comp_field) +{ + OSMO_ASSERT(comp_field); + + if (comp_field->rfc1144_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rfc2507_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rohc_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->v42bis_params) + return SNDCP_XID_DATA_COMPRESSION; + else if (comp_field->v44_params) + return SNDCP_XID_DATA_COMPRESSION; + else + return -EINVAL; +} + +/* Convert all compression fields to bytstreams */ +static int gprs_sndcp_pack_fields(const struct llist_head *comp_fields, + uint8_t *dst, + unsigned int dst_maxlen, int class) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int rc; + + llist_for_each_entry_reverse(comp_field, comp_fields, list) { + if (class == gprs_sndcp_get_compression_class(comp_field)) { + rc = encode_comp_field(dst + byte_counter, + dst_maxlen - byte_counter, + comp_field); + + /* When input data is correct, there is + * no reason for the encoder to fail! */ + OSMO_ASSERT(rc >= 0); + + byte_counter += rc; + } + } + + /* Return generated length */ + return byte_counter; +} + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields) +{ + int rc; + int byte_counter = 0; + uint8_t comp_bytes[512]; + uint8_t xid_version_number[1] = { CURRENT_SNDCP_VERSION }; + + OSMO_ASSERT(comp_fields); + OSMO_ASSERT(dst); + OSMO_ASSERT(dst_maxlen >= 2 + sizeof(xid_version_number)); + + /* Bail if there is no input */ + if (llist_empty(comp_fields)) + return -EINVAL; + + /* Prepend header */ + dst = + tlv_put(dst, SNDCP_XID_VERSION_NUMBER, + sizeof(xid_version_number), xid_version_number); + byte_counter += (sizeof(xid_version_number) + 2); + + /* Add data compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_DATA_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_DATA_COMPRESSION, rc, comp_bytes); + byte_counter += rc + 2; + } + + /* Add header compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_PROTOCOL_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_PROTOCOL_COMPRESSION, rc, + comp_bytes); + byte_counter += rc + 2; + } + + /* Return generated length */ + return byte_counter; +} + +/* FUNCTIONS RELATED TO SNDCP-XID DECODING */ + +/* Decode applicable sapis (works the same in all three compression schemes) */ +static int decode_pcomp_applicable_sapis(uint8_t *nsapis, + uint8_t *nsapis_len, + const uint8_t *src, + unsigned int src_len) +{ + uint16_t blob; + int i; + int nsapi_len = 0; + + /* Exit immediately if no result can be stored */ + if (!nsapis) + return -EINVAL; + + /* Exit immediately if not enough input data is available */ + if (src_len < 2) + return -EINVAL; + + /* Read bitmask */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= (*src) & 0xFF; + blob = (blob >> 5); + + /* Decode applicable SAPIs */ + for (i = 0; i < 15; i++) { + if ((blob >> i) & 1) { + nsapis[nsapi_len] = i + 5; + nsapi_len++; + } + } + + /* Return consumed length */ + *nsapis_len = nsapi_len; + return 2; +} + +/* Decode 16 bit field */ +static int decode_pcomp_16_bit_field(int *value_int, uint16_t * value_uint16, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint16_t blob; + + /* Reset values to zero (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint16) + *value_uint16 = 0; + + /* Exit if not enough src are available */ + if (src_len < 2) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint16) + *value_uint16 = blob; + + /* Return consumed length */ + return 2; +} + +/* Decode 8 bit field */ +static int decode_pcomp_8_bit_field(int *value_int, uint8_t *value_uint8, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint8_t blob; + + /* Reset values to invalid (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint8) + *value_uint8 = 0; + + /* Exit if not enough src are available */ + if (src_len < 1) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint8) + *value_uint8 = blob; + + /* Return consumed length */ + return 1; +} + +/* Decode rfc1144 parameter field see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int decode_pcomp_rfc1144_params(struct gprs_sndcp_pcomp_rfc1144_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->s01 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode parameter S0 -1 + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + rc = decode_pcomp_8_bit_field(¶ms->s01, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ +static int decode_pcomp_rfc2507_params(struct gprs_sndcp_pcomp_rfc2507_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->f_max_period = -1; + params->f_max_time = -1; + params->max_header = -1; + params->tcp_space = -1; + params->non_tcp_space = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->f_max_period, NULL, src, + src_len - byte_counter, 1, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->f_max_time, NULL, src, + src_len - byte_counter, 1, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->tcp_space, NULL, src, + src_len - byte_counter, 3, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->non_tcp_space, NULL, src, + src_len - byte_counter, 3, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode ROHC parameter field (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int decode_pcomp_rohc_params(struct gprs_sndcp_pcomp_rohc_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + int i; + + /* Mark all optional parameters invalid by default */ + params->max_cid = -1; + params->max_header = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_cid, NULL, src, + src_len - byte_counter, 0, 16383); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < 16; i++) { + params->profile_len = 0; + rc = decode_pcomp_16_bit_field(NULL, ¶ms->profile[i], src, + src_len - byte_counter, 0, + 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + params->profile_len = i + 1; + } + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int decode_dcomp_v42bis_params(struct gprs_sndcp_dcomp_v42bis_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->p0 = -1; + params->p1 = -1; + params->p2 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_16_bit_field(¶ms->p1, NULL, src, + src_len - byte_counter, 512, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p2, NULL, src, + src_len - byte_counter, 6, 250); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V44 parameter field (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->c0 = -1; + params->p0 = -1; + params->p1t = -1; + params->p1r = -1; + params->p3t = -1; + params->p3r = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->c0, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + if ((params->c0 != 0x80) && (params->c0 != 0xC0)) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3t < 2 * params->p1t) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3r < 2 * params->p1r) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Lookup algorithm identfier by entity ID */ +static int lookup_algorithm_identifier(int entity, const struct + entity_algo_table + *lt, unsigned int lt_len, int compclass) +{ + int i; + + if (!lt) + return -1; + + for (i = 0; i < lt_len; i++) { + if ((lt[i].entity == entity) + && (lt[i].compclass == compclass)) + return lt[i].algo; + } + + return -1; +} + +/* Helper function for decode_comp_field(), decodes + * numeric pcomp/dcomp values */ +static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int compclass) +{ + int src_counter = 0; + int i; + + if (comp_field->p) { + /* Determine the number of expected PCOMP/DCOMP values */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + /* For protocol compression */ + switch (comp_field->algo) { + case RFC_1144: + comp_field->comp_len = RFC1144_PCOMP_NUM; + break; + case RFC_2507: + comp_field->comp_len = RFC2507_PCOMP_NUM; + break; + case ROHC: + comp_field->comp_len = ROHC_PCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } else { + /* For data compression */ + switch (comp_field->algo) { + case V42BIS: + comp_field->comp_len = V42BIS_DCOMP_NUM; + break; + case V44: + comp_field->comp_len = V44_DCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } + + for (i = 0; i < comp_field->comp_len; i++) { + if (i & 1) { + comp_field->comp[i] = (*src) & 0x0F; + src++; + src_counter++; + } else + comp_field->comp[i] = ((*src) >> 4) & 0x0F; + } + + if (i & 1) { + src++; + src_counter++; + } + } + + return src_counter; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are protocol compression specific */ +static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case RFC_1144: + comp_field->rfc1144_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc1144_params); + rc = decode_pcomp_rfc1144_params(comp_field->rfc1144_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case RFC_2507: + comp_field->rfc2507_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc2507_params); + rc = decode_pcomp_rfc2507_params(comp_field->rfc2507_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case ROHC: + comp_field->rohc_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rohc_params); + rc = decode_pcomp_rohc_params(comp_field->rohc_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->rohc_params); + break; + + /* If no suitable decoder is detected, + leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->rfc1144_params = NULL; + comp_field->rfc2507_params = NULL; + comp_field->rohc_params = NULL; + } + + return rc; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are data compression specific */ +static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case V42BIS: + comp_field->v42bis_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v42bis_params); + rc = decode_dcomp_v42bis_params(comp_field->v42bis_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v42bis_params); + break; + case V44: + comp_field->v44_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v44_params); + rc = decode_dcomp_v44_params(comp_field->v44_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v44_params); + break; + + /* If no suitable decoder is detected, + * leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->v42bis_params = NULL; + comp_field->v44_params = NULL; + } + + return rc; +} + +/* Decode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, unsigned int src_len, + const struct entity_algo_table *lt, + unsigned int lt_len, int compclass) +{ + int src_counter = 0; + unsigned int len; + int rc; + + OSMO_ASSERT(comp_field); + + /* Exit immediately if it is clear that no + parseable data is present */ + if (src_len < 1 || !src) + return -EINVAL; + + /* Zero out target struct */ + memset(comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Decode Propose bit and Entity number */ + if ((*src) & 0x80) + comp_field->p = 1; + comp_field->entity = (*src) & 0x1F; + src_counter++; + src++; + + /* Decode algorithm number (if present) */ + if (comp_field->p) { + comp_field->algo = (*src) & 0x1F; + src_counter++; + src++; + } + /* Alternatively take the information from the lookup table */ + else + comp_field->algo = + lookup_algorithm_identifier(comp_field->entity, lt, + lt_len, compclass); + + /* Decode length field */ + len = *src; + src_counter++; + src++; + + /* Decode PCOMP/DCOMP values */ + rc = decode_comp_values(comp_field, src, compclass); + if (rc < 0) + return -EINVAL; + src_counter += rc; + src += rc; + len -= rc; + + /* Decode algorithm specific payload data */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = decode_pcomp_params(comp_field, src, len); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = decode_dcomp_params(comp_field, src, len); + else + return -EINVAL; + + if (rc >= 0) + src_counter += rc; + else + return -EINVAL; + + /* Return consumed length */ + return src_counter; +} + +/* Helper function for gprs_sndcp_decode_xid() to decode XID blocks */ +static int decode_xid_block(struct llist_head *comp_fields, uint8_t tag, + uint16_t tag_len, const uint8_t *val, + const struct entity_algo_table *lt, + unsigned int lt_len) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int comp_field_count = 0; + int rc; + + byte_counter = 0; + do { + /* Bail if more than the maximum number of + comp_fields is generated */ + if (comp_field_count > MAX_ENTITIES * 2) { + return -EINVAL; + } + + /* Parse and add comp_field */ + comp_field = + talloc_zero(comp_fields, struct gprs_sndcp_comp_field); + + rc = decode_comp_field(comp_field, val + byte_counter, + tag_len - byte_counter, lt, lt_len, tag); + + if (rc < 0) { + talloc_free(comp_field); + return -EINVAL; + } + + byte_counter += rc; + llist_add(&comp_field->list, comp_fields); + comp_field_count++; + } + while (tag_len - byte_counter > 0); + + return byte_counter; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +static int gprs_sndcp_decode_xid(struct llist_head *comp_fields, + const uint8_t *src, unsigned int src_len, + const struct + entity_algo_table + *lt, unsigned int lt_len) +{ + int src_pos = 0; + uint8_t tag; + uint16_t tag_len; + const uint8_t *val; + int byte_counter = 0; + int rc; + int tlv_count = 0; + + /* Valid TLV-Tag and types */ + static const struct tlv_definition sndcp_xid_def = { + .def = { + [SNDCP_XID_VERSION_NUMBER] = {TLV_TYPE_TLV,}, + [SNDCP_XID_DATA_COMPRESSION] = {TLV_TYPE_TLV,}, + [SNDCP_XID_PROTOCOL_COMPRESSION] = {TLV_TYPE_TLV,}, + }, + }; + + /* Parse TLV-Encoded SNDCP-XID message and defer payload + to the apporpiate sub-parser functions */ + while (1) { + + /* Bail if an the maximum number of TLV fields + * have been parsed */ + if (tlv_count >= 3) { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Parse TLV field */ + rc = tlv_parse_one(&tag, &tag_len, &val, &sndcp_xid_def, + src + src_pos, src_len - src_pos); + if (rc > 0) + src_pos += rc; + else { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Decode compression parameters */ + if ((tag == SNDCP_XID_PROTOCOL_COMPRESSION) + || (tag == SNDCP_XID_DATA_COMPRESSION)) { + rc = decode_xid_block(comp_fields, tag, tag_len, val, + lt, lt_len); + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } else + byte_counter += rc; + } + + /* Stop when no further TLV elements can be expected */ + if (src_len - src_pos <= 2) + break; + + tlv_count++; + } + + return 0; +} + +/* Fill up lookutable from a list with comression entitiy fields */ +static int gprs_sndcp_fill_table(struct + entity_algo_table *lt, + unsigned int lt_len, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field; + int i = 0; + + if (!comp_fields) + return -EINVAL; + if (!lt) + return -EINVAL; + + memset(lt, 0, lt_len * sizeof(lt)); + + llist_for_each_entry(comp_field, comp_fields, list) { + + lt[i].entity = comp_field->entity; + lt[i].algo = comp_field->algo; + lt[i].compclass = gprs_sndcp_get_compression_class(comp_field); + + if (lt[i].compclass < 0) { + memset(lt, 0, lt_len * sizeof(lt)); + return -EINVAL; + } + + i++; + } + + return i; +} + +/* Complete comp field params + * (if a param (dst) is not valid, it will be copied from source (src) */ +static int complete_comp_field_params(struct gprs_sndcp_comp_field + *comp_field_dst, const struct + gprs_sndcp_comp_field *comp_field_src) +{ + if (comp_field_dst->algo < 0) + return -EINVAL; + + if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) { + if (comp_field_dst->rfc1144_params->s01 < 0) { + comp_field_dst->rfc1144_params->s01 = + comp_field_src->rfc1144_params->s01; + } + return 0; + } + + if (comp_field_dst->rfc2507_params && comp_field_src->rfc2507_params) { + + if (comp_field_dst->rfc2507_params->f_max_period < 0) { + comp_field_dst->rfc2507_params->f_max_period = + comp_field_src->rfc2507_params->f_max_period; + } + if (comp_field_dst->rfc2507_params->f_max_time < 0) { + comp_field_dst->rfc2507_params->f_max_time = + comp_field_src->rfc2507_params->f_max_time; + } + if (comp_field_dst->rfc2507_params->max_header < 0) { + comp_field_dst->rfc2507_params->max_header = + comp_field_src->rfc2507_params->max_header; + } + if (comp_field_dst->rfc2507_params->tcp_space < 0) { + comp_field_dst->rfc2507_params->tcp_space = + comp_field_src->rfc2507_params->tcp_space; + } + if (comp_field_dst->rfc2507_params->non_tcp_space < 0) { + comp_field_dst->rfc2507_params->non_tcp_space = + comp_field_src->rfc2507_params->non_tcp_space; + } + return 0; + } + + if (comp_field_dst->rohc_params && comp_field_src->rohc_params) { + if (comp_field_dst->rohc_params->max_cid < 0) { + comp_field_dst->rohc_params->max_cid = + comp_field_src->rohc_params->max_cid; + } + if (comp_field_dst->rohc_params->max_header < 0) { + comp_field_dst->rohc_params->max_header = + comp_field_src->rohc_params->max_header; + } + if (comp_field_dst->rohc_params->profile_len > 0) { + memcpy(comp_field_dst->rohc_params->profile, + comp_field_src->rohc_params->profile, + sizeof(comp_field_dst->rohc_params->profile)); + comp_field_dst->rohc_params->profile_len = + comp_field_src->rohc_params->profile_len; + } + + return 0; + } + + if (comp_field_dst->v42bis_params && comp_field_src->v42bis_params) { + if (comp_field_dst->v42bis_params->p0 < 0) { + comp_field_dst->v42bis_params->p0 = + comp_field_src->v42bis_params->p0; + } + if (comp_field_dst->v42bis_params->p1 < 0) { + comp_field_dst->v42bis_params->p1 = + comp_field_src->v42bis_params->p1; + } + if (comp_field_dst->v42bis_params->p2 < 0) { + comp_field_dst->v42bis_params->p2 = + comp_field_src->v42bis_params->p2; + } + return 0; + } + + if (comp_field_dst->v44_params && comp_field_src->v44_params) { + if (comp_field_dst->v44_params->c0 < 0) { + comp_field_dst->v44_params->c0 = + comp_field_src->v44_params->c0; + } + if (comp_field_dst->v44_params->p0 < 0) { + comp_field_dst->v44_params->p0 = + comp_field_src->v44_params->p0; + } + if (comp_field_dst->v44_params->p1t < 0) { + comp_field_dst->v44_params->p1t = + comp_field_src->v44_params->p1t; + } + if (comp_field_dst->v44_params->p1r < 0) { + comp_field_dst->v44_params->p1r = + comp_field_src->v44_params->p1r; + } + if (comp_field_dst->v44_params->p3t < 0) { + comp_field_dst->v44_params->p3t = + comp_field_src->v44_params->p3t; + } + if (comp_field_dst->v44_params->p3r < 0) { + comp_field_dst->v44_params->p3r = + comp_field_src->v44_params->p3r; + } + return 0; + } + + /* There should be at least exist one param set + * in the destination struct, otherwise something + * must be wrong! */ + return -EINVAL; +} + +/* Complete missing parameters in a comp_field */ +static int gprs_sndcp_complete_comp_field(struct gprs_sndcp_comp_field + *comp_field, const struct llist_head + *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_src; + int rc = 0; + + llist_for_each_entry(comp_field_src, comp_fields, list) { + if (comp_field_src->entity == comp_field->entity) { + + /* Complete header fields */ + if (comp_field_src->comp_len > 0) { + memcpy(comp_field->comp, + comp_field_src->comp, + sizeof(comp_field_src->comp)); + comp_field->comp_len = comp_field_src->comp_len; + } + + /* Complete parameter fields */ + rc = complete_comp_field_params(comp_field, + comp_field_src); + } + } + + return rc; +} + +/* Complete missing parameters of all comp_field in a list */ +static int gprs_sndcp_complete_comp_fields(struct llist_head + *comp_fields_incomplete, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_incomplete; + int rc; + + llist_for_each_entry(comp_field_incomplete, comp_fields_incomplete, + list) { + + rc = gprs_sndcp_complete_comp_field(comp_field_incomplete, + comp_fields); + if (rc < 0) + return -EINVAL; + + } + + return 0; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t *src, + unsigned int src_len, + const struct llist_head + *comp_fields_req) +{ + int rc; + int lt_len; + struct llist_head *comp_fields; + struct entity_algo_table lt[MAX_ENTITIES * 2]; + + OSMO_ASSERT(src); + + comp_fields = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(comp_fields); + + if (comp_fields_req) { + /* Generate lookup table */ + lt_len = + gprs_sndcp_fill_table(lt, MAX_ENTITIES * 2, + comp_fields_req); + if (lt_len < 0) { + talloc_free(comp_fields); + return NULL; + } + + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, lt, + lt_len); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + rc = gprs_sndcp_complete_comp_fields(comp_fields, + comp_fields_req); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + } else { + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, NULL, 0); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + } + + return comp_fields; +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * dumps protocol compression parameters */ +static void dump_pcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case RFC_1144: + if (comp_field->rfc1144_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc1144_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc1144_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc1144_params->nsapi_len); + if (comp_field->rfc1144_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc1144_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc1144_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " s01=%d;\n", + comp_field->rfc1144_params->s01); + LOGP(DSNDCP, logl, " }\n"); + break; + case RFC_2507: + if (comp_field->rfc2507_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc2507_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc2507_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc2507_params->nsapi_len); + if (comp_field->rfc2507_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc2507_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc2507_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " f_max_period=%d;\n", + comp_field->rfc2507_params->f_max_period); + LOGP(DSNDCP, logl, + " f_max_time=%d;\n", + comp_field->rfc2507_params->f_max_time); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rfc2507_params->max_header); + LOGP(DSNDCP, logl, + " tcp_space=%d;\n", + comp_field->rfc2507_params->tcp_space); + LOGP(DSNDCP, logl, + " non_tcp_space=%d;\n", + comp_field->rfc2507_params->non_tcp_space); + LOGP(DSNDCP, logl, " }\n"); + break; + case ROHC: + if (comp_field->rohc_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rohc_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rohc_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rohc_params->nsapi_len); + if (comp_field->rohc_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rohc_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " max_cid=%d;\n", comp_field->rohc_params->max_cid); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rohc_params->max_header); + LOGP(DSNDCP, logl, + " profile_len=%d;\n", + comp_field->rohc_params->profile_len); + if (comp_field->rohc_params->profile_len == 0) + LOGP(DSNDCP, logl, " profile[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->profile_len; i++) + LOGP(DSNDCP, logl, + " profile[%d]=%04x;\n", + i, comp_field->rohc_params->profile[i]); + LOGP(DSNDCP, logl, " }\n"); + break; + } + +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * data protocol compression parameters */ +static void dump_dcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case V42BIS: + if (comp_field->v42bis_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v42bis_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v42bis_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v42bis_params->nsapi_len); + if (comp_field->v42bis_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v42bis_params->nsapi_len; i++) + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v42bis_params->nsapi[i]); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v42bis_params->p0); + LOGP(DSNDCP, logl, " p1=%d;\n", + comp_field->v42bis_params->p1); + LOGP(DSNDCP, logl, " p2=%d;\n", + comp_field->v42bis_params->p2); + LOGP(DSNDCP, logl, " }\n"); + break; + case V44: + if (comp_field->v44_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v44_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v44_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v44_params->nsapi_len); + if (comp_field->v44_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v44_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v44_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " c0=%d;\n", + comp_field->v44_params->c0); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v44_params->p0); + LOGP(DSNDCP, logl, " p1t=%d;\n", + comp_field->v44_params->p1t); + LOGP(DSNDCP, logl, " p1r=%d;\n", + comp_field->v44_params->p1r); + LOGP(DSNDCP, logl, " p3t=%d;\n", + comp_field->v44_params->p3t); + LOGP(DSNDCP, logl, " p3r=%d;\n", + comp_field->v44_params->p3r); + LOGP(DSNDCP, logl, " }\n"); + break; + } +} + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl) +{ + struct gprs_sndcp_comp_field *comp_field; + int i; + int compclass; + + OSMO_ASSERT(comp_fields); + + llist_for_each_entry(comp_field, comp_fields, list) { + LOGP(DSNDCP, logl, "SNDCP-XID:\n"); + LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n"); + LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity); + LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo); + LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len); + if (comp_field->comp_len == 0) + LOGP(DSNDCP, logl, " comp[] = NULL;\n"); + for (i = 0; i < comp_field->comp_len; i++) { + LOGP(DSNDCP, logl, " comp[%d]=%d;\n", i, + comp_field->comp[i]); + } + + compclass = gprs_sndcp_get_compression_class(comp_field); + + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + dump_pcomp_params(comp_field, logl); + } else if (compclass == SNDCP_XID_DATA_COMPRESSION) { + dump_dcomp_params(comp_field, logl); + } + + LOGP(DSNDCP, logl, "}\n"); + } + +} diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 7396c52..7b145f7 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -10,7 +10,9 @@ subscr \ mm_auth \ xid \ + sndcp_xid \ $(NULL) + if BUILD_NAT SUBDIRS += \ bsc-nat \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index d148c48..cf88101 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -56,7 +56,8 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -66,7 +67,9 @@ $(LIBCRYPTO_LIBS) \ $(LIBGTP_LIBS) \ -lrt \ + -lm \ $(NULL) + if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ diff --git a/openbsc/tests/sndcp_xid/Makefile.am b/openbsc/tests/sndcp_xid/Makefile.am new file mode 100644 index 0000000..99b9d1a --- /dev/null +++ b/openbsc/tests/sndcp_xid/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = sndcp_xid_test.ok + +noinst_PROGRAMS = sndcp_xid_test + +sndcp_xid_test_SOURCES = sndcp_xid_test.c + +sndcp_xid_test_LDADD = \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp -lrt -lm + + diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.c b/openbsc/tests/sndcp_xid/sndcp_xid_test.c new file mode 100644 index 0000000..3a33619 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.c @@ -0,0 +1,282 @@ +/* Test SNDCP-XID Encoding/Decoding */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include + +/* Test SNDCP-XID decoding with a real world sample */ +static void test_xid_decode_realworld(const void *ctx) +{ + struct llist_head *comp_fields; + int rc; + printf("Testing SNDCP XID-Decoder/Encoder (real world data)\n"); + + /* Example of a real world SNDCP-XID message */ + uint8_t xid[] = + { 0x00, 0x01, 0x00, 0x02, 0x31, 0x82, 0x02, 0x27, 0x89, 0xff, 0xe0, + 0x00, 0x0f, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, + 0x01, 0x02, 0x00, 0x03, 0x01, 0x03, 0x00, 0x04, 0x01, 0x04, 0x00, 0x05, + 0x01, 0x05, 0x00, 0x06, 0x00, 0x07, 0x01, 0x07, 0x00, 0x08, 0x01, 0x08, + 0x80, 0x00, 0x04, 0x12, 0x00, 0x40, 0x07 }; + uint8_t xid_r[512]; + + /* Parse and show contained comp fields */ + comp_fields = gprs_sndcp_parse_xid(ctx, xid, sizeof(xid), NULL); + OSMO_ASSERT(comp_fields); + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields, DSNDCP); + + /* Encode comp-fields again */ + rc = gprs_sndcp_compile_xid(xid_r,sizeof(xid_r), comp_fields); + printf("Result length=%i\n",rc); + printf("Encoded: %s\n", osmo_hexdump_nospc(xid, sizeof(xid))); + printf("Rencoded: %s\n", osmo_hexdump_nospc(xid_r, rc)); + + OSMO_ASSERT(rc == 54); + OSMO_ASSERT(memcmp(xid, xid_r, sizeof(xid)) == 0); + + /* Free comp fields */ + talloc_free(comp_fields); + + printf("\n"); +} + +/* Encode and decode test with artificial test data */ +static void test_xid_encode_decode(const void *ctx) +{ + printf("Testing SNDCP XID-Encoder/Decoder\n"); + + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_pcomp_rfc2507_params rfc2507_params; + struct gprs_sndcp_comp_field rfc2507_comp_field; + struct gprs_sndcp_pcomp_rohc_params rohc_params; + struct gprs_sndcp_comp_field rohc_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; + struct gprs_sndcp_dcomp_v44_params v44_params; + struct gprs_sndcp_comp_field v44_comp_field; + struct llist_head *comp_fields_dec; + + uint8_t xid[512]; + unsigned int xid_len = sizeof(xid); + int rc; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rfc2507_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rohc_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v44_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc1144_params.nsapi[0] = 5; + rfc1144_params.nsapi_len = 1; + + /* Setup rfc1144 operating parameters */ + rfc1144_params.s01 = 7; + + /* Setup rfc1144 compression field */ + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = 0; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc2507_params.nsapi[0] = 6; + rfc2507_params.nsapi_len = 1; + + /* Setup rfc2507 operating parameters */ + rfc2507_params.f_max_period = 256; + rfc2507_params.f_max_time = 5; + rfc2507_params.max_header = 168; + rfc2507_params.tcp_space = 15; + rfc2507_params.non_tcp_space = 15; + + /* Setup rfc2507 compression field */ + rfc2507_comp_field.p = 1; + rfc2507_comp_field.entity = 1; + rfc2507_comp_field.algo = RFC_2507; + rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3; + rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4; + rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5; + rfc2507_comp_field.comp[RFC2507_PCOMP4] = 6; + rfc2507_comp_field.comp[RFC2507_PCOMP5] = 7; + rfc2507_comp_field.comp_len = RFC2507_PCOMP_NUM; + rfc2507_comp_field.rfc2507_params = &rfc2507_params; + + /* Setup which NSAPIs shall make use of ROHC */ + rohc_params.nsapi[0] = 5; + rohc_params.nsapi[1] = 6; + rohc_params.nsapi[2] = 7; + rohc_params.nsapi[3] = 8; + rohc_params.nsapi[4] = 9; + rohc_params.nsapi[5] = 10; + rohc_params.nsapi[6] = 11; + rohc_params.nsapi[7] = 12; + rohc_params.nsapi[8] = 13; + rohc_params.nsapi[9] = 14; + rohc_params.nsapi[10] = 15; + rohc_params.nsapi_len = 11; + + /* Setup ROHC operating parameters */ + rohc_params.max_cid = 15; /* default */ + rohc_params.max_header = 168; /* default */ + rohc_params.profile[0] = ROHC_UNCOMPRESSED; + rohc_params.profile[1] = ROHC_RTP; + rohc_params.profile[2] = ROHCV2_RTP; + rohc_params.profile[3] = ROHC_UDP; + rohc_params.profile[4] = ROHCv2_UDP; + rohc_params.profile[5] = ROHC_ESP; + rohc_params.profile[6] = ROHCV2_ESP; + rohc_params.profile[7] = ROHC_IP; + rohc_params.profile[8] = ROHCV2_IP; + rohc_params.profile[9] = ROHC_LLA; + rohc_params.profile[10] = ROHC_LLA_WITH_R_MODE; + rohc_params.profile[11] = ROHC_TCP; + rohc_params.profile[12] = ROHC_RTP_UDP_LITE; + rohc_params.profile[13] = ROHCV2_RTP_UDP_LITE; + rohc_params.profile[14] = ROHC_UDP_LITE; + rohc_params.profile[15] = ROHCV2_UDP_LITE; + rohc_params.profile_len = 16; + + /* Setup ROHC compression field */ + rohc_comp_field.p = 1; + rohc_comp_field.entity = 2; + rohc_comp_field.algo = ROHC; + rohc_comp_field.comp[ROHC_PCOMP1] = 8; + rohc_comp_field.comp[ROHC_PCOMP2] = 9; + rohc_comp_field.comp_len = ROHC_PCOMP_NUM; + rohc_comp_field.rohc_params = &rohc_params; + + /* Setup which NSAPIs shall make use of v42bis */ + v42bis_params.nsapi[0] = 5; + v42bis_params.nsapi_len = 1; + + /* Setup v42bis operating parameters */ + v42bis_params.p0 = 3; + v42bis_params.p1 = 2048; + v42bis_params.p2 = 20; + + /* Setup v42bis compression field */ + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = 3; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 10; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + + /* Setup which NSAPIs shall make use of v44 */ + v44_params.nsapi[0] = 5; + v44_params.nsapi_len = 1; + + /* Setup v44 operating parameters */ + v44_params.c0 = 0x80; + v44_params.p0 = 3; + v44_params.p1t = 300; + v44_params.p1r = 300; + v44_params.p3t = 600; + v44_params.p3r = 600; + + /* Setup v44 compression field */ + v44_comp_field.p = 1; + v44_comp_field.entity = 3; + v44_comp_field.algo = V44; + v44_comp_field.comp[V44_DCOMP1] = 10; + v44_comp_field.comp[V44_DCOMP2] = 11; + v44_comp_field.comp_len = V44_DCOMP_NUM; + v44_comp_field.v44_params = &v44_params; + + /* Add compression field(s) to list */ + llist_add(&v44_comp_field.list, &comp_fields); + llist_add(&v42bis_comp_field.list, &comp_fields); + llist_add(&rfc1144_comp_field.list, &comp_fields); + llist_add(&rfc2507_comp_field.list, &comp_fields); + llist_add(&rohc_comp_field.list, &comp_fields); + printf("Test input data:\n"); + gprs_sndcp_dump_comp_fields(&comp_fields, DSNDCP); + + /* Encode SNDCP-XID fields */ + rc = gprs_sndcp_compile_xid(xid, xid_len, &comp_fields); + OSMO_ASSERT(rc > 0); + + printf("Encoded: %s (%i bytes)\n", osmo_hexdump_nospc(xid, rc), rc); + + /* Parse and show contained comp fields */ + comp_fields_dec = gprs_sndcp_parse_xid(ctx, xid, rc, NULL); + OSMO_ASSERT(comp_fields_dec); + + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields_dec, DSNDCP); + + /* Free comp fields */ + talloc_free(comp_fields_dec); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *xid_ctx; + + osmo_init_logging(&info); + + xid_ctx = talloc_named_const(NULL, 0, "xid_ctx"); + + test_xid_decode_realworld(xid_ctx); + test_xid_encode_decode(xid_ctx); + + printf("Done\n"); + + talloc_report_full(xid_ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.ok b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok new file mode 100644 index 0000000..f357282 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok @@ -0,0 +1,11 @@ +Testing SNDCP XID-Decoder/Encoder (real world data) +Decoded: +Result length=54 +Encoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 +Rencoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 + +Testing SNDCP XID-Encoder/Decoder +Test input data: +Encoded: 000100011a83010dab00208003012c012c02580258830007a000200308001402408000041200200781010c3456700040010005a80f000f82022789ffe0000f00a80000000101010002010200030103000401040005010500060007010700080108 (97 bytes) +Decoded: +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 6470ab9..85a81d6 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -129,3 +129,10 @@ cat $abs_srcdir/xid/xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([sndcp_xid]) +AT_KEYWORDS([sndcp_xid]) +cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) +AT_CLEANUP + -- To view, visit https://gerrit.osmocom.org/641 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e Gerrit-PatchSet: 16 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:00:44 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#30). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,459 insertions(+), 28 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/30 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 12e1a66..e28c507 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,8 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_comp.h \ + gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..4e15b9b --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 22809b7..9537c0a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 06c12d7..c044f24 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -71,6 +71,8 @@ gprs_gmm.c \ gprs_sgsn.c \ gprs_sndcp.c \ + gprs_sndcp_comp.c \ + gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ sgsn_main.c \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index a2ffa51..7124103 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -525,11 +547,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..a7877c1 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -143,6 +268,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +301,58 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +513,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +551,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +617,40 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + /* Apply header compression */ + rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + } +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +672,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +692,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +715,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +745,70 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } #if 0 @@ -619,3 +868,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..544ad52 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,280 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + uint8_t *data_o; + + /* Create a working copy of the incoming data */ + data_o = talloc_zero_size(NULL, len); + memcpy(data_o, data, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + memcpy(data, data_o, compr_len); + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + memcpy(data, data_o, compr_len); + } else + *pcomp_index = 0; + + talloc_free(data_o); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 04bd40a..9f65325 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef BUILD_IU #include @@ -317,6 +318,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -324,7 +327,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index bab3f0e..1447577 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -59,6 +59,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 30 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:00:44 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/803 to look at the new patch set (#5). SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 593 insertions(+), 22 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/03/803/5 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 3014d5f..c6a0149 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -26,6 +26,7 @@ gprs_sgsn.h \ gprs_sndcp.h \ gprs_sndcp_comp.h \ + gprs_sndcp_dcomp.h \ gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..a76b4a4 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,53 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 9537c0a..786e2b2 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3970ba6..d228b39 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -72,6 +72,7 @@ gprs_sgsn.c \ gprs_sndcp.c \ gprs_sndcp_comp.c \ + gprs_sndcp_dcomp.c \ gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index a7877c1..197c4e7 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -314,13 +315,25 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -345,7 +358,8 @@ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, sne->nsapi, msg, npdu_len, expnd); - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) talloc_free(expnd); return rc; @@ -630,7 +644,8 @@ DEBUGP(DSNDCP, "===================================================\n"); debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { /* Apply header compression */ rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, @@ -638,6 +653,19 @@ if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + + /* Apply data compression */ + rc = gprs_sndcp_dcomp_compress(msg->data, msg->len, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); return -EIO; } @@ -774,13 +802,25 @@ DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); DEBUGP(DSNDCP, "===================================================\n"); #endif - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -805,7 +845,8 @@ rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, expnd); - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) talloc_free(expnd); return rc; @@ -876,8 +917,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -893,6 +937,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -1000,13 +1061,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->v42bis_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..7520546 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,357 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void v42bis_reset(v42bis_state_t *comp) +{ + /* This function performs a complete reset of the V.42bis compression + * state by reinitalizing the state withe the previously negotiated + * parameters. */ + + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + uint8_t *data_o; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Run compressor */ + data_o = talloc_zero_size(NULL, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_o; + compressed_data.buf_pointer = data_o; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + talloc_free(data_o); + return len; + } + + *pcomp_index = 1; + memcpy(data, data_o, compressed_data.len); + talloc_free(data_o); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int v42bis_expand_unitdata(uint8_t *data, unsigned int len, + uint8_t pcomp_index, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + int rc; + struct v42bis_output_buffer uncompressed_data; + uint8_t *data_i; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Decompress packet */ + data_i = talloc_zero_size(NULL, len); + memcpy(data_i, data, len); + uncompressed_data.buf = data; + uncompressed_data.buf_pointer = data; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + talloc_free(data_i); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = v42bis_expand_unitdata(data, len, pcomp_index, comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = v42bis_compress_unitdata(&pcomp_index, data, len, + comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 9f3260d..fb5b6d5 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -299,6 +299,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 9250632..9ee5455 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -62,6 +62,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:00:44 +0000 Subject: [PATCH] openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/644 to look at the new patch set (#38). V.42bis: integration and unit test - Edit previously committed V.42bis implementation to function outside IAXmodem. - Add unit test to verify the correct function of V.42bis Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h M openbsc/include/openbsc/v42bis.h M openbsc/include/openbsc/v42bis_private.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/v42bis.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/testsuite.at A openbsc/tests/v42bis/Makefile.am A openbsc/tests/v42bis/v42bis_test.c A openbsc/tests/v42bis/v42bis_test.ok 14 files changed, 1,135 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/44/644/38 -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 38 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:00:44 +0000 Subject: [PATCH] openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/635 to look at the new patch set (#19). RFC1144: integration and unit-test The previously pushed slhc implementation has been modified to compile and function outside of the kernel. Also debug log messages were added and datatypes ware matched. The implementation is now ready to be used Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h R openbsc/include/openbsc/slhc.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/slhc.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/slhc/Makefile.am A openbsc/tests/slhc/slhc_test.c A openbsc/tests/slhc/slhc_test.ok M openbsc/tests/testsuite.at 14 files changed, 543 insertions(+), 88 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/635/19 diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 8ce3b70..e75b9eb 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -83,6 +83,7 @@ tests/mm_auth/mm_auth_test tests/xid/xid_test tests/sndcp_xid/sndcp_xid_test +tests/slhc/slhc_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 9dc2f8d..cebabdc 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -232,6 +232,7 @@ tests/mm_auth/Makefile tests/xid/Makefile tests/sndcp_xid/Makefile + tests/slhc/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index a91322f..12e1a66 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -65,6 +65,7 @@ sgsn.h \ signal.h \ silent_call.h \ + slhc.h \ smpp.h \ sms_queue.h \ socket.h \ diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 43ebb19..90ddca5 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -29,6 +29,7 @@ DBSSGP, DLLC, DSNDCP, + DSLHC, DNAT, DCTRL, DSMPP, diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc.h similarity index 97% rename from openbsc/include/openbsc/slhc_vj.h rename to openbsc/include/openbsc/slhc.h index 8716d59..cd5a47c 100644 --- a/openbsc/include/openbsc/slhc_vj.h +++ b/openbsc/include/openbsc/slhc.h @@ -171,7 +171,8 @@ #define NULLSLCOMPR (struct slcompress *)0 /* In slhc.c: */ -struct slcompress *slhc_init(int rslots, int tslots); +struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); + void slhc_free(struct slcompress *comp); int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, @@ -180,4 +181,7 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); int slhc_toss(struct slcompress *comp); +void slhc_i_status(struct slcompress *comp); +void slhc_o_status(struct slcompress *comp); + #endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3b58399..06c12d7 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -87,6 +87,7 @@ gprs_gsup_client.c \ sgsn_cdr.c \ sgsn_ares.c \ + slhc.c \ oap.c \ oap_messages.c \ gprs_llc_xid.c \ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 7d533c0..9f3260d 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -294,6 +294,11 @@ .description = "SCCP User Adaptation (SUA)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DSLHC] = { + .name = "DSLHC", + .description = "RFC1144 TCP/IP Header compression (SLHC)", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c index 27ed252..cbdf8db 100644 --- a/openbsc/src/gprs/slhc.c +++ b/openbsc/src/gprs/slhc.c @@ -50,61 +50,77 @@ * driver code belonging close to PPP and SLIP */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef CONFIG_INET -/* Entire module is for IP only */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#define ERR_PTR(x) x + static unsigned char *encode(unsigned char *cp, unsigned short n); static long decode(unsigned char **cpp); static unsigned char * put16(unsigned char *cp, unsigned short x); static unsigned short pull16(unsigned char **cpp); +/* Replacement for kernel space function ip_fast_csum() */ +static uint16_t ip_fast_csum(uint8_t *iph, int ihl) +{ + int i; + uint16_t temp; + uint32_t accumulator = 0xFFFF; + + for(i=0;i0xFFFF) + { + accumulator++; + accumulator&=0xFFFF; + } + } + + return (uint16_t)(htons(~accumulator)&0xFFFF); +} + +/* Replacement for kernel space function put_unaligned() */ +static void put_unaligned(uint16_t val, void *ptr) +{ + memcpy(ptr,&val,sizeof(val)); +} + + /* Allocate compression data structure * slots must be in range 0 to 255 (zero meaning no compression) * Returns pointer to structure or ERR_PTR() on error. */ struct slcompress * -slhc_init(int rslots, int tslots) +slhc_init(const void *ctx, int rslots, int tslots) { register short i; register struct cstate *ts; struct slcompress *comp; if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) - return ERR_PTR(-EINVAL); + return NULL; - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = (struct slcompress *)talloc_zero_size(ctx,sizeof(struct slcompress)); if (! comp) goto out_fail; if (rslots > 0) { size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = kzalloc(rsize, GFP_KERNEL); + comp->rstate = (struct cstate *) talloc_zero_size(ctx, rsize); if (! comp->rstate) goto out_free; comp->rslot_limit = rslots - 1; @@ -112,7 +128,7 @@ if (tslots > 0) { size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = kzalloc(tsize, GFP_KERNEL); + comp->tstate = (struct cstate *) talloc_zero_size(ctx, tsize); if (! comp->tstate) goto out_free2; comp->tslot_limit = tslots - 1; @@ -141,11 +157,11 @@ return comp; out_free2: - kfree(comp->rstate); + talloc_free(comp->rstate); out_free: - kfree(comp); + talloc_free(comp); out_fail: - return ERR_PTR(-ENOMEM); + return NULL; } @@ -153,16 +169,18 @@ void slhc_free(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_free(): Freeing compression states...\n"); + if ( comp == NULLSLCOMPR ) return; if ( comp->tstate != NULLSLSTATE ) - kfree( comp->tstate ); + talloc_free(comp->tstate ); if ( comp->rstate != NULLSLSTATE ) - kfree( comp->rstate ); + talloc_free( comp->rstate ); - kfree( comp ); + talloc_free( comp ); } @@ -187,6 +205,8 @@ } else { *cp++ = n; } + + DEBUGP(DSLHC, "encode(): n=%04x\n",n); return cp; } @@ -256,6 +276,7 @@ comp->sls_o_nontcp++; else comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Not a TCP packat, will not touch...\n"); return isize; } /* Extract TCP header */ @@ -271,6 +292,7 @@ ! (th->ack)){ /* TCP connection stuff; send as regular IP */ comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Packet is part of a TCP connection, will not touch...\n"); return isize; } /* @@ -287,6 +309,9 @@ * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ + + DEBUGP(DSLHC, "slhc_compress(): Compressible packet detected!\n"); + for ( ; ; ) { if( ip->saddr == cs->cs_ip.saddr && ip->daddr == cs->cs_ip.daddr @@ -310,11 +335,14 @@ * state points to the newest and we only need to set * xmit_oldest to update the lru linkage. */ + + DEBUGP(DSLHC, "slhc_compress(): Header not yet seen, will memorize header for the next turn...\n"); comp->sls_o_misses++; comp->xmit_oldest = lcs->cs_this; goto uncompressed; found: + DEBUGP(DSLHC, "slhc_compress(): Header already seen, trying to compress...\n"); /* * Found it -- move to the front on the connection list. */ @@ -344,6 +372,39 @@ */ oth = &cs->cs_tcp; + /* Display a little more debug information about which of the + * header fields changed unexpectedly */ + if(ip->version != cs->cs_ip.version) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->version != cs->cs_ip.version\n"); + if(ip->ihl != cs->cs_ip.ihl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ihl != cs->cs_ip.ihl\n"); + if(ip->tos != cs->cs_ip.tos) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->tos != cs->cs_ip.tos\n"); + if((ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))\n"); + if(ip->ttl != cs->cs_ip.ttl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ttl != cs->cs_ip.ttl\n"); + if(th->doff != cs->cs_tcp.doff) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: th->doff != cs->cs_tcp.doff\n"); + if(ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): ip->ihl = %i\n", ip->ihl); + DEBUGP(DSLHC, "slhc_compress(): ip+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(ip+1),((ip->ihl)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: cs->cs_ipopt = %s\n", + osmo_hexdump_nospc((uint8_t*)(cs->cs_ipopt),((ip->ihl)-5)*4)); + } + if(th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): th->doff = %i\n", th->doff); + DEBUGP(DSLHC, "slhc_compress(): th+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(th+1),((th->doff)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): cs->cs_tcpopt = %s\n", + osmo_hexdump_nospc((uint8_t*)cs->cs_tcpopt, + ((th->doff)-5)*4)); + } + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl || ip->tos != cs->cs_ip.tos || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) @@ -351,6 +412,7 @@ || th->doff != cs->cs_tcp.doff || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + DEBUGP(DSLHC, "slhc_compress(): The header contains unexpected changes, can't compress...\n"); goto uncompressed; } @@ -362,6 +424,7 @@ */ if(th->urg){ deltaS = ntohs(th->urg_ptr); + DEBUGP(DSLHC, "slhc_compress(): flag: Urgent Pointer (U) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_U; } else if(th->urg_ptr != oth->urg_ptr){ @@ -369,21 +432,29 @@ * implementation should never do this but RFC793 * doesn't prohibit the change so we have to deal * with it. */ + DEBUGP(DSLHC, "slhc_compress(): URG not set but urp changed, can't compress...\n"); goto uncompressed; } if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Window (W) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_W; } if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ - if(deltaA > 0x0000ffff) + if(deltaA > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Ack (A) = 1\n"); cp = encode(cp,deltaA); changes |= NEW_A; } if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ - if(deltaS > 0x0000ffff) + if(deltaS > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_S; } @@ -399,17 +470,21 @@ if(ip->tot_len != cs->cs_ip.tot_len && ntohs(cs->cs_ip.tot_len) == hlen) break; + DEBUGP(DSLHC, "slhc_compress(): Retransmitted packet detected, can't compress...\n"); goto uncompressed; case SPECIAL_I: case SPECIAL_D: /* actual changes match one of our special case encodings -- * send packet uncompressed. */ + DEBUGP(DSLHC, "slhc_compress(): Special case detected, can't compress...\n"); goto uncompressed; case NEW_S|NEW_A: if(deltaS == deltaA && deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_compress(): Special case for echoed terminal traffic detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_I; cp = new_seq; } @@ -417,6 +492,8 @@ case NEW_S: if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for data xfer */ + DEBUGP(DSLHC, "slhc_compress(): Special case for data xfer detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Ack (A) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_D; cp = new_seq; } @@ -424,11 +501,14 @@ } deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); if(deltaS != 1){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta IP ID (I) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_I; } - if(th->psh) + if(th->psh) { + DEBUGP(DSLHC, "slhc_compress(): flag: Push (P) = 1\n"); changes |= TCP_PUSH_BIT; + } /* Grab the cksum before we overwrite it below. Then update our * state with this packet's header. */ @@ -445,6 +525,7 @@ if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ cp = ocp; *cpp = ocp; + DEBUGP(DSLHC, "slhc_compress(): flag: Connection number (C) = 1\n"); *cp++ = changes | NEW_C; *cp++ = cs->cs_this; comp->xmit_current = cs->cs_this; @@ -456,6 +537,10 @@ *(__sum16 *)cp = csum; cp += 2; /* deltaS is now the size of the change section of the compressed header */ + + DEBUGP(DSLHC, "slhc_compress(): Delta-list length (deltaS) = %li\n",deltaS); + DEBUGP(DSLHC, "slhc_compress(): Original header len (hlen) = %i\n",hlen); + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ memcpy(cp+deltaS,icp+hlen,isize-hlen); comp->sls_o_compressed++; @@ -467,6 +552,7 @@ * to use on future compressed packets in the protocol field). */ uncompressed: + DEBUGP(DSLHC, "slhc_compress(): Packet will be sent uncompressed...\n"); memcpy(&cs->cs_ip,ip,20); memcpy(&cs->cs_tcp,th,20); if (ip->ihl > 5) @@ -538,6 +624,8 @@ switch(changes & SPECIALS_MASK){ case SPECIAL_I: /* Echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_uncompress(): Echoed terminal traffic detected\n"); + { register short i; i = ntohs(ip->tot_len) - hdrlen; @@ -547,11 +635,13 @@ break; case SPECIAL_D: /* Unidirectional data */ + DEBUGP(DSLHC, "slhc_uncompress(): Unidirectional data detected\n"); thp->seq = htonl( ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen); break; default: + DEBUGP(DSLHC, "slhc_uncompress(): default packet type detected\n"); if(changes & NEW_U){ thp->urg = 1; if((x = decode(&cp)) == -1) { @@ -601,6 +691,7 @@ ip->tot_len = htons(len); ip->check = 0; + DEBUGP(DSLHC, "slhc_uncompress(): making space for the reconstructed header...\n"); memmove(icp + hdrlen, cp, len - hdrlen); cp = icp; @@ -625,6 +716,7 @@ return len; bad: + DEBUGP(DSLHC, "slhc_uncompress(): bad packet detected!\n"); comp->sls_i_error++; return slhc_toss( comp ); } @@ -641,6 +733,7 @@ if(isize < 20) { /* The packet is shorter than a legal IP header */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The packet is shorter than a legal IP header ==> slhc_toss()\n"); return slhc_toss( comp ); } /* Peek at the IP header's IHL field to find its length */ @@ -648,6 +741,7 @@ if(ihl < 20 / 4){ /* The IP header length field is too small */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The IP header length field is too small ==> slhc_toss()\n"); return slhc_toss( comp ); } index = icp[9]; @@ -656,10 +750,12 @@ if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; + DEBUGP(DSLHC, "slhc_remember(): Bad IP header checksum; discard ==> slhc_toss()\n"); return slhc_toss( comp ); } if(index > comp->rslot_limit) { comp->sls_i_error++; + DEBUGP(DSLHC, "slhc_remember(): index > comp->rslot_limit ==> slhc_toss()\n"); return slhc_toss(comp); } @@ -683,6 +779,7 @@ int slhc_toss(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_toss(): Reset compression state...\n"); if ( comp == NULLSLCOMPR ) return 0; @@ -690,55 +787,27 @@ return 0; } -#else /* CONFIG_INET */ - -int -slhc_toss(struct slcompress *comp) +void slhc_i_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); - return -EINVAL; -} -int -slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); - return -EINVAL; -} -int -slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_i_status(): %d Cmp, %d Uncmp, %d Bad, %d Tossed\n", + comp->sls_i_compressed, + comp->sls_i_uncompressed, + comp->sls_i_error, + comp->sls_i_tossed); + } } -int -slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +void slhc_o_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_o_status(): %d Cmp, %d Uncmp, %d AsIs, %d NotTCP %d Searches, %d Misses\n", + comp->sls_o_compressed, + comp->sls_o_uncompressed, + comp->sls_o_tcp, + comp->sls_o_nontcp, + comp->sls_o_searches, + comp->sls_o_misses); + } } -void -slhc_free(struct slcompress *comp) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); -} -struct slcompress * -slhc_init(int rslots, int tslots) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); - return NULL; -} - -#endif /* CONFIG_INET */ - -/* VJ header compression */ -EXPORT_SYMBOL(slhc_init); -EXPORT_SYMBOL(slhc_free); -EXPORT_SYMBOL(slhc_remember); -EXPORT_SYMBOL(slhc_compress); -EXPORT_SYMBOL(slhc_uncompress); -EXPORT_SYMBOL(slhc_toss); - -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 7b145f7..2e342e0 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -11,6 +11,7 @@ mm_auth \ xid \ sndcp_xid \ + slhc \ $(NULL) if BUILD_NAT diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index cf88101..bab3f0e 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -58,6 +58,7 @@ $(top_builddir)/src/gprs/oap_messages.o \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(top_builddir)/src/gprs/slhc.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ diff --git a/openbsc/tests/slhc/Makefile.am b/openbsc/tests/slhc/Makefile.am new file mode 100644 index 0000000..32a3cc4 --- /dev/null +++ b/openbsc/tests/slhc/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = slhc_test.ok + +noinst_PROGRAMS = slhc_test + +slhc_test_SOURCES = slhc_test.c + +slhc_test_LDADD = \ + $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) + + diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c new file mode 100644 index 0000000..59a5425 --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.c @@ -0,0 +1,298 @@ +/* Test SLHC/RFC1144 TCP/IP Header compression/decompression */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +/* Number of compression slots (S0-1) */ +#define SLOTS 8 + +/* Maximum packet bytes to display */ +#define DISP_MAX_BYTES 100 + +/* Sample packets to test with */ +#define PACKETS_LEN 6 +char *packets[] = { + "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", + "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", + "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", + "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" +}; + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int compress(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + uint8_t *comp_ptr; /* Not used */ + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int expand(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + int data_decompressed_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Handle an uncompressed packet (learn header information */ + if ((data_i[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Calculate IP Header checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Check TCP/IP packet */ +static void check_packet(const void *ctx, uint8_t *packet, int len) +{ + /* Check IP header */ + OSMO_ASSERT(len > 20); + OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + + /* Check TCP packet */ + if (packet[9] != 0x06) + return; + OSMO_ASSERT(len > 40); + OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); +} + +/* Strip TCP options from TCP/IP packet */ +static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) +{ + uint8_t doff; + uint16_t csum; + + /* Check if the packet can be handled here */ + if (len < 37) + return len; + if (packet[9] != 0x06) + return len; + + /* Strip TCP/IP options from packet */ + doff = ((packet[32] >> 4) & 0x0F) * 4; + memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); + len = len - (doff - 20); + + /* Repair data offset (TCP header length) */ + packet[32] &= 0x0F; + packet[32] |= 0x50; + + /* Repair checksum */ + packet[36] = 0; + packet[37] = 0; + csum = calc_tcpip_csum(ctx, packet, len); + packet[36] = csum & 0xFF; + packet[37] = csum >> 8 & 0xFF; + + /* Repair total length */ + packet[3] = len & 0xFF; + packet[2] = len >> 8 & 0xFF; + + /* Repair IP header checksum */ + packet[10] = 0; + packet[11] = 0; + csum = calc_ip_csum(packet, 20); + packet[10] = csum & 0xFF; + packet[11] = csum >> 8 & 0xFF; + printf("csum=%04x\n", csum); + + return len; +} + +/* Compress / Decompress packets */ +static void test_slhc(const void *ctx) +{ + char packet_ascii[2048]; + int i; + + struct slcompress *comp; + uint8_t packet[1024]; + int packet_len; + uint8_t packet_compr[1024]; + int packet_compr_len; + uint8_t packet_decompr[1024]; + int packet_decompr_len; + + printf("Allocating compression state...\n"); + comp = slhc_init(ctx, SLOTS, SLOTS); + OSMO_ASSERT(comp); + + for(i=0;i DISP_MAX_BYTES) + packet_compr_len = DISP_MAX_BYTES; + if (packet_len > DISP_MAX_BYTES) + packet_len = DISP_MAX_BYTES; + if (packet_decompr_len > DISP_MAX_BYTES) + packet_decompr_len = DISP_MAX_BYTES; + printf("Original Packet: (%i bytes) %s\n", packet_len, + osmo_hexdump_nospc(packet, packet_len)); + printf("DecompressedPacket: (%i bytes) %s\n", + packet_decompr_len, osmo_hexdump_nospc(packet_decompr, + packet_decompr_len)); + printf("CompressedPacket: (%i bytes) %s\n", packet_compr_len, + osmo_hexdump_nospc(packet_compr, packet_compr_len)); + slhc_o_status(comp); + slhc_o_status(comp); + + printf("\n"); + } + + printf("Freeing compression state...\n"); + slhc_free(comp); + printf("\n"); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + }, + [DSLHC] = { + .name = "DSLHC", + .description = + "Van Jacobson RFC1144 TCP/IP header compression (SLHC)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *ctx; + + osmo_init_logging(&info); + + ctx = talloc_named_const(NULL, 0, "slhc_ctx"); + + test_slhc(ctx); + + printf("Done\n"); + + talloc_report_full(ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/slhc/slhc_test.ok b/openbsc/tests/slhc/slhc_test.ok new file mode 100644 index 0000000..636241d --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.ok @@ -0,0 +1,52 @@ +Allocating compression state... +csum=b3a9 +Compressing... +Decompressing... +Results: +Original Packet: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +DecompressedPacket: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +CompressedPacket: (52 bytes) 7510003446dd40004000a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 + +csum=97a9 +Compressing... +Decompressing... +Results: +Original Packet: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +DecompressedPacket: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +CompressedPacket: (43 bytes) df00cda4fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 + +csum=baa9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +DecompressedPacket: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +CompressedPacket: (9 bytes) dc00a70a5227fffd01 + +csum=b9a9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +DecompressedPacket: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +CompressedPacket: (7 bytes) db00a706fffb01 + +csum=7ba9 +Compressing... +Decompressing... +Results: +Original Packet: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +DecompressedPacket: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +CompressedPacket: (68 bytes) db00c2d00d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a + +csum=aca9 +Compressing... +Decompressing... +Results: +Original Packet: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +DecompressedPacket: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +CompressedPacket: (18 bytes) df0021fb706f6c6c7578206c6f67696e3a20 + +Freeing compression state... + +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 85a81d6..5f37b8e 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -136,3 +136,8 @@ AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([slhc]) +AT_KEYWORDS([slhc]) +cat $abs_srcdir/slhc/slhc_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 19 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 19 15:48:34 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 19 Sep 2016 15:48:34 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#31). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,466 insertions(+), 31 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/31 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 12e1a66..e28c507 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,8 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_comp.h \ + gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..4e15b9b --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 22809b7..9537c0a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 06c12d7..c044f24 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -71,6 +71,8 @@ gprs_gmm.c \ gprs_sgsn.c \ gprs_sndcp.c \ + gprs_sndcp_comp.c \ + gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ sgsn_main.c \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index a2ffa51..ff771b8 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -269,9 +291,13 @@ gprs_llc_process_xid_ind(gph->data, gph->data_len, response, sizeof(response), lle); - xid = msgb_put(resp, response_len); - memcpy(xid, response, response_len); - + if (response_len < 0) { + LOGP(DLLC, LOGL_ERROR, + "invalid XID indication received!\n"); + } else { + xid = msgb_put(resp, response_len); + memcpy(xid, response, response_len); + } gprs_llc_tx_xid(lle, resp, 0); } else { LOGP(DLLC, LOGL_NOTICE, @@ -525,11 +551,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..a7877c1 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -143,6 +268,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +301,58 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +513,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +551,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +617,40 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + /* Apply header compression */ + rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + } +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +672,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +692,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +715,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +745,70 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + talloc_free(expnd); + + return rc; } #if 0 @@ -619,3 +868,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..544ad52 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,280 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + uint8_t *data_o; + + /* Create a working copy of the incoming data */ + data_o = talloc_zero_size(NULL, len); + memcpy(data_o, data, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + memcpy(data, data_o, compr_len); + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + memcpy(data, data_o, compr_len); + } else + *pcomp_index = 0; + + talloc_free(data_o); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 04bd40a..9f65325 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef BUILD_IU #include @@ -317,6 +318,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -324,7 +327,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index bab3f0e..1447577 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -59,6 +59,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 31 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 20 08:01:41 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 08:01:41 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show EPDAN bug Message-ID: Review at https://gerrit.osmocom.org/861 EGPRS: add test case to show EPDAN bug This patch adds a test case test_tbf_egprs_epdan which expects a current bug with EPDAN for Interpretation of the bitmap explained in section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. the specification explains that A bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored. But current PCU implementation ignores EPDAN The test's expectation is corrected along with the bug fix in a subsequent commit Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Related: OS#1789 --- M src/rlc.h M tests/tbf/TbfTest.cpp 2 files changed, 126 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/61/861/1 diff --git a/src/rlc.h b/src/rlc.h index b693418..2baf134 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -302,6 +302,9 @@ const uint16_t v_a() const; const int16_t distance() const; + void set_v_s(int); + void set_v_a(int); + /* Methods to manage reception */ int resend_needed(); int mark_for_resend(); @@ -509,6 +512,16 @@ return m_v_s; } +inline void gprs_rlc_dl_window::set_v_s(int v_s) +{ + m_v_s = v_s; +} + +inline void gprs_rlc_dl_window::set_v_a(int v_a) +{ + m_v_a = v_a; +} + inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const { return mod_sns(m_v_s + offset); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3e17d8f..5be5686 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -26,6 +26,7 @@ #include "pcu_utils.h" #include "gprs_bssgp_pcu.h" #include "pcu_l1_if.h" +#include "decoding.h" extern "C" { #include "pcu_vty.h" @@ -2016,6 +2017,117 @@ printf("=== end %s ===\n", __func__); } +/* + * This test simulates the section 9.1.8.2.4 of 44.060 + * version 7.27.0 Release 7. which explains the Interpretation of the bitmap + * as a bit within the uncompressed bitmap whose BSN is not within the transmit + * window shall be ignored. Which fails because of existing bug. This test case + * expects the same bug. which shall be fixed in subsequent patch + */ +static void egprs_tbf_epdan_outof_rx_window(BTS *the_bts, int mcs) +{ + unsigned i; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + uint32_t fn = 2654167; /* 17,25,9 */ + uint8_t trx_no; + int num_blocks; + uint32_t tlli = 0xffeeddcc; + uint8_t rbb[64/8]; + gprs_rlcmac_dl_tbf *dl_tbf; + int ts_no = 7; + bitvec *block; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + EGPRS_PD_AckNack_t *ack_nack; + RlcMacUplink_t ul_control_block; + gprs_rlcmac_bts *bts; + + /* + * Over the Air message captured. The same has been used + * used to simulate the EPDAN out of window scenario. During + * over the air testing, v_a was 1176, vs was 1288, max sns was 2048 + * and window size of 480. same has been used below + */ + uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1, + 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f, + 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + bts = the_bts->bts_data(); + + bts->initial_mcs_dl = mcs; + + dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no); + dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + + dl_tbf->m_window.set_v_s(1288); + dl_tbf->m_window.set_v_a(1176); + dl_tbf->m_window.set_sns(2048); + dl_tbf->m_window.set_ws(480); + dl_tbf->m_window.m_v_b.mark_unacked(1176); + dl_tbf->m_window.m_v_b.mark_unacked(1177); + dl_tbf->m_window.m_v_b.mark_unacked(1287); + dl_tbf->m_window.m_v_b.mark_unacked(1286); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + block = bitvec_alloc(23); + + bitvec_unpack(block, data_msg); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + decode_gsm_rlcmac_uplink(block, &ul_control_block); + + ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack; + + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &dl_tbf->m_window); + + dl_tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + + bitvec_free(block); + tbf_free(dl_tbf); +} + +static void test_tbf_egprs_epdan(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + int i; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + /* ARQ II */ + bts->dl_arq_type = EGPRS_ARQ2; + + egprs_tbf_epdan_outof_rx_window(&the_bts, 4); + + printf("=== end %s ===\n", __func__); +} static void test_tbf_egprs_two_phase_spb(void) { @@ -2695,6 +2807,7 @@ test_tbf_puan_urbb_len(); test_tbf_update_ws(); test_tbf_li_decoding(); + test_tbf_egprs_epdan(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 20 08:01:41 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 08:01:41 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: fix for EPDAN out of window Message-ID: Review at https://gerrit.osmocom.org/862 EGPRS: fix for EPDAN out of window Fix for aligning the EPDAN out of RLC transmit window is made according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that A bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored Related: OS#1789 Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 --- M src/rlc.cpp M src/tbf_dl.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 5 files changed, 165 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/62/862/1 diff --git a/src/rlc.cpp b/src/rlc.cpp index ee2635a..b544d6a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -105,7 +105,8 @@ uint16_t first_bsn, uint16_t *lost, uint16_t *received) { - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)distance() + ? distance() : rbb->cur_bit; unsigned bsn; /* first_bsn is in range V(A)..V(S) */ diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 457f2c9..656b9a7 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -845,10 +845,11 @@ uint16_t bsn = 0; unsigned received_bytes = 0, lost_bytes = 0; unsigned received_packets = 0, lost_packets = 0; - unsigned num_blocks = strlen(show_rbb); + unsigned num_blocks = strlen(show_rbb) > (unsigned)m_window.distance() + ? m_window.distance() : strlen(show_rbb); /* SSN - 1 is in range V(A)..V(S)-1 */ - for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { + for (unsigned bitpos = 0; bitpos < num_blocks; bitpos++) { bool is_received; int index = num_blocks - 1 - bitpos; @@ -925,7 +926,8 @@ char show_rbb[RLC_MAX_SNS + 1]; int error_rate; struct ana_result ana_res; - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance() + ? m_window.distance() : rbb->cur_bit; unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks); Decoding::extract_rbb(rbb, show_rbb); @@ -948,8 +950,7 @@ * TODO: check whether this FIXME still makes sense */ LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " - "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); - return 1; /* indicate to free TBF */ + "V(A)..V(S) range %s\n", tbf_name(this)); } } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 5be5686..eced0da 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -2098,10 +2098,10 @@ ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, bsn_begin, &bits); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1286)); bitvec_free(block); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0c9c877..4297444 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -446,7 +446,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=85)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=20) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=127, info='RRRRRRRRRRRRRRRRRRRRR$..........................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRR...........................................' - got ack for BSN=20 - got ack for BSN=19 - got ack for BSN=18 @@ -485,7 +485,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=86)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=21) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=20, info='R$..............................................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=21, info='R...............................................................' - got ack for BSN=21 - V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -6521,3 +6521,152 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1287) R=ACK I=NACK +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=1176:1288, lost=0, recv=0, skipped=112, bsn=1944, info='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx................................................................................................................................................................................................................................................................................................................................................................................' +- got ack for BSN=1176 +- got ack for BSN=1177 +- got ack for BSN=1178 +- got ack for BSN=1179 +- got ack for BSN=1180 +- got ack for BSN=1181 +- got ack for BSN=1182 +- got ack for BSN=1183 +- got ack for BSN=1184 +- got ack for BSN=1185 +- got NACK for BSN=1186 +- got NACK for BSN=1187 +- got NACK for BSN=1188 +- got NACK for BSN=1189 +- got NACK for BSN=1190 +- got NACK for BSN=1191 +- got NACK for BSN=1192 +- got NACK for BSN=1193 +- got NACK for BSN=1194 +- got NACK for BSN=1195 +- got NACK for BSN=1196 +- got NACK for BSN=1197 +- got NACK for BSN=1198 +- got NACK for BSN=1199 +- got NACK for BSN=1200 +- got NACK for BSN=1201 +- got NACK for BSN=1202 +- got NACK for BSN=1203 +- got NACK for BSN=1204 +- got NACK for BSN=1205 +- got NACK for BSN=1206 +- got NACK for BSN=1207 +- got NACK for BSN=1208 +- got NACK for BSN=1209 +- got NACK for BSN=1210 +- got NACK for BSN=1211 +- got NACK for BSN=1212 +- got NACK for BSN=1213 +- got NACK for BSN=1214 +- got NACK for BSN=1215 +- got NACK for BSN=1216 +- got NACK for BSN=1217 +- got NACK for BSN=1218 +- got NACK for BSN=1219 +- got NACK for BSN=1220 +- got NACK for BSN=1221 +- got NACK for BSN=1222 +- got NACK for BSN=1223 +- got NACK for BSN=1224 +- got NACK for BSN=1225 +- got NACK for BSN=1226 +- got NACK for BSN=1227 +- got NACK for BSN=1228 +- got NACK for BSN=1229 +- got NACK for BSN=1230 +- got NACK for BSN=1231 +- got NACK for BSN=1232 +- got NACK for BSN=1233 +- got NACK for BSN=1234 +- got NACK for BSN=1235 +- got NACK for BSN=1236 +- got NACK for BSN=1237 +- got NACK for BSN=1238 +- got NACK for BSN=1239 +- got NACK for BSN=1240 +- got NACK for BSN=1241 +- got NACK for BSN=1242 +- got NACK for BSN=1243 +- got NACK for BSN=1244 +- got NACK for BSN=1245 +- got NACK for BSN=1246 +- got NACK for BSN=1247 +- got NACK for BSN=1248 +- got NACK for BSN=1249 +- got NACK for BSN=1250 +- got NACK for BSN=1251 +- got NACK for BSN=1252 +- got NACK for BSN=1253 +- got NACK for BSN=1254 +- got NACK for BSN=1255 +- got NACK for BSN=1256 +- got NACK for BSN=1257 +- got ack for BSN=1258 +- got ack for BSN=1259 +- got ack for BSN=1260 +- got NACK for BSN=1261 +- got ack for BSN=1262 +- got ack for BSN=1263 +- got ack for BSN=1264 +- got ack for BSN=1265 +- got ack for BSN=1266 +- got ack for BSN=1267 +- got ack for BSN=1268 +- got ack for BSN=1269 +- got ack for BSN=1270 +- got ack for BSN=1271 +- got ack for BSN=1272 +- got ack for BSN=1273 +- got ack for BSN=1274 +- got ack for BSN=1275 +- got ack for BSN=1276 +- got ack for BSN=1277 +- got ack for BSN=1278 +- got ack for BSN=1279 +- got ack for BSN=1280 +- got ack for BSN=1281 +- got ack for BSN=1282 +- got ack for BSN=1283 +- got ack for BSN=1284 +- got ack for BSN=1285 +- got ack for BSN=1286 +- got ack for BSN=1287 +- V(B): (V(A)=1186)"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAANAAAAAAAAAAAAAAAAAAAAAAAAAA"(V(S)-1=1287) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid +DL packet loss of IMSI= / TLLI=0xffeeddcc: 78% +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index eb870ea..bbc0af6 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -66,3 +66,5 @@ === end test_tbf_update_ws === === start test_tbf_li_decoding === === end test_tbf_li_decoding === +=== start test_tbf_egprs_epdan === +=== end test_tbf_egprs_epdan === -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 20 09:13:39 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 09:13:39 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/861 to look at the new patch set (#2). EGPRS: add test case to show EPDAN BSN out of window bug This patch adds a test case test_tbf_egprs_epdan which expects a current bug with EPDAN for Interpretation of the bitmap explained in section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. the specification explains that A bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored. But current PCU implementation ignores EPDAN The test's expectation is corrected along with the bug fix in a subsequent commit Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Related: OS#1789 --- M src/rlc.h M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 4 files changed, 164 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/61/861/2 diff --git a/src/rlc.h b/src/rlc.h index b693418..2baf134 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -302,6 +302,9 @@ const uint16_t v_a() const; const int16_t distance() const; + void set_v_s(int); + void set_v_a(int); + /* Methods to manage reception */ int resend_needed(); int mark_for_resend(); @@ -509,6 +512,16 @@ return m_v_s; } +inline void gprs_rlc_dl_window::set_v_s(int v_s) +{ + m_v_s = v_s; +} + +inline void gprs_rlc_dl_window::set_v_a(int v_a) +{ + m_v_a = v_a; +} + inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const { return mod_sns(m_v_s + offset); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3e17d8f..5be5686 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -26,6 +26,7 @@ #include "pcu_utils.h" #include "gprs_bssgp_pcu.h" #include "pcu_l1_if.h" +#include "decoding.h" extern "C" { #include "pcu_vty.h" @@ -2016,6 +2017,117 @@ printf("=== end %s ===\n", __func__); } +/* + * This test simulates the section 9.1.8.2.4 of 44.060 + * version 7.27.0 Release 7. which explains the Interpretation of the bitmap + * as a bit within the uncompressed bitmap whose BSN is not within the transmit + * window shall be ignored. Which fails because of existing bug. This test case + * expects the same bug. which shall be fixed in subsequent patch + */ +static void egprs_tbf_epdan_outof_rx_window(BTS *the_bts, int mcs) +{ + unsigned i; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + uint32_t fn = 2654167; /* 17,25,9 */ + uint8_t trx_no; + int num_blocks; + uint32_t tlli = 0xffeeddcc; + uint8_t rbb[64/8]; + gprs_rlcmac_dl_tbf *dl_tbf; + int ts_no = 7; + bitvec *block; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + EGPRS_PD_AckNack_t *ack_nack; + RlcMacUplink_t ul_control_block; + gprs_rlcmac_bts *bts; + + /* + * Over the Air message captured. The same has been used + * used to simulate the EPDAN out of window scenario. During + * over the air testing, v_a was 1176, vs was 1288, max sns was 2048 + * and window size of 480. same has been used below + */ + uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1, + 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f, + 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + bts = the_bts->bts_data(); + + bts->initial_mcs_dl = mcs; + + dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no); + dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + + dl_tbf->m_window.set_v_s(1288); + dl_tbf->m_window.set_v_a(1176); + dl_tbf->m_window.set_sns(2048); + dl_tbf->m_window.set_ws(480); + dl_tbf->m_window.m_v_b.mark_unacked(1176); + dl_tbf->m_window.m_v_b.mark_unacked(1177); + dl_tbf->m_window.m_v_b.mark_unacked(1287); + dl_tbf->m_window.m_v_b.mark_unacked(1286); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + block = bitvec_alloc(23); + + bitvec_unpack(block, data_msg); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + decode_gsm_rlcmac_uplink(block, &ul_control_block); + + ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack; + + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &dl_tbf->m_window); + + dl_tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + + bitvec_free(block); + tbf_free(dl_tbf); +} + +static void test_tbf_egprs_epdan(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + int i; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + /* ARQ II */ + bts->dl_arq_type = EGPRS_ARQ2; + + egprs_tbf_epdan_outof_rx_window(&the_bts, 4); + + printf("=== end %s ===\n", __func__); +} static void test_tbf_egprs_two_phase_spb(void) { @@ -2695,6 +2807,7 @@ test_tbf_puan_urbb_len(); test_tbf_update_ws(); test_tbf_li_decoding(); + test_tbf_egprs_epdan(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0c9c877..877e0ad 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6521,3 +6521,39 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK +- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF! +DL packet loss of IMSI= / TLLI=0xffeeddcc: 100% +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index eb870ea..bbc0af6 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -66,3 +66,5 @@ === end test_tbf_update_ws === === start test_tbf_li_decoding === === end test_tbf_li_decoding === +=== start test_tbf_egprs_epdan === +=== end test_tbf_egprs_epdan === -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 20 09:13:39 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 09:13:39 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: fix for EPDAN out of window In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/862 to look at the new patch set (#2). EGPRS: fix for EPDAN out of window Fix for aligning the EPDAN out of RLC transmit window is made according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that A bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored Related: OS#1789 Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 --- M src/rlc.cpp M src/tbf_dl.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 4 files changed, 129 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/62/862/2 diff --git a/src/rlc.cpp b/src/rlc.cpp index ee2635a..b544d6a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -105,7 +105,8 @@ uint16_t first_bsn, uint16_t *lost, uint16_t *received) { - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)distance() + ? distance() : rbb->cur_bit; unsigned bsn; /* first_bsn is in range V(A)..V(S) */ diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 457f2c9..fe85e4d 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -845,7 +845,8 @@ uint16_t bsn = 0; unsigned received_bytes = 0, lost_bytes = 0; unsigned received_packets = 0, lost_packets = 0; - unsigned num_blocks = strlen(show_rbb); + unsigned num_blocks = strlen(show_rbb) > (unsigned)m_window.distance() + ? m_window.distance() : strlen(show_rbb); /* SSN - 1 is in range V(A)..V(S)-1 */ for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { @@ -925,7 +926,8 @@ char show_rbb[RLC_MAX_SNS + 1]; int error_rate; struct ana_result ana_res; - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance() + ? m_window.distance() : rbb->cur_bit; unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks); Decoding::extract_rbb(rbb, show_rbb); @@ -948,8 +950,7 @@ * TODO: check whether this FIXME still makes sense */ LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " - "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); - return 1; /* indicate to free TBF */ + "V(A)..V(S) range %s\n", tbf_name(this)); } } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 5be5686..eced0da 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -2098,10 +2098,10 @@ ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, bsn_begin, &bits); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287)); - OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1176)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1177)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1287)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1286)); bitvec_free(block); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 877e0ad..4297444 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -446,7 +446,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=85)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=20) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=127, info='RRRRRRRRRRRRRRRRRRRRR$..........................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRR...........................................' - got ack for BSN=20 - got ack for BSN=19 - got ack for BSN=18 @@ -485,7 +485,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=86)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=21) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=20, info='R$..............................................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=21, info='R...............................................................' - got ack for BSN=21 - V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -6547,9 +6547,122 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge -- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK -- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF! -DL packet loss of IMSI= / TLLI=0xffeeddcc: 100% +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1287) R=ACK I=NACK +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=1176:1288, lost=0, recv=0, skipped=112, bsn=1944, info='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx................................................................................................................................................................................................................................................................................................................................................................................' +- got ack for BSN=1176 +- got ack for BSN=1177 +- got ack for BSN=1178 +- got ack for BSN=1179 +- got ack for BSN=1180 +- got ack for BSN=1181 +- got ack for BSN=1182 +- got ack for BSN=1183 +- got ack for BSN=1184 +- got ack for BSN=1185 +- got NACK for BSN=1186 +- got NACK for BSN=1187 +- got NACK for BSN=1188 +- got NACK for BSN=1189 +- got NACK for BSN=1190 +- got NACK for BSN=1191 +- got NACK for BSN=1192 +- got NACK for BSN=1193 +- got NACK for BSN=1194 +- got NACK for BSN=1195 +- got NACK for BSN=1196 +- got NACK for BSN=1197 +- got NACK for BSN=1198 +- got NACK for BSN=1199 +- got NACK for BSN=1200 +- got NACK for BSN=1201 +- got NACK for BSN=1202 +- got NACK for BSN=1203 +- got NACK for BSN=1204 +- got NACK for BSN=1205 +- got NACK for BSN=1206 +- got NACK for BSN=1207 +- got NACK for BSN=1208 +- got NACK for BSN=1209 +- got NACK for BSN=1210 +- got NACK for BSN=1211 +- got NACK for BSN=1212 +- got NACK for BSN=1213 +- got NACK for BSN=1214 +- got NACK for BSN=1215 +- got NACK for BSN=1216 +- got NACK for BSN=1217 +- got NACK for BSN=1218 +- got NACK for BSN=1219 +- got NACK for BSN=1220 +- got NACK for BSN=1221 +- got NACK for BSN=1222 +- got NACK for BSN=1223 +- got NACK for BSN=1224 +- got NACK for BSN=1225 +- got NACK for BSN=1226 +- got NACK for BSN=1227 +- got NACK for BSN=1228 +- got NACK for BSN=1229 +- got NACK for BSN=1230 +- got NACK for BSN=1231 +- got NACK for BSN=1232 +- got NACK for BSN=1233 +- got NACK for BSN=1234 +- got NACK for BSN=1235 +- got NACK for BSN=1236 +- got NACK for BSN=1237 +- got NACK for BSN=1238 +- got NACK for BSN=1239 +- got NACK for BSN=1240 +- got NACK for BSN=1241 +- got NACK for BSN=1242 +- got NACK for BSN=1243 +- got NACK for BSN=1244 +- got NACK for BSN=1245 +- got NACK for BSN=1246 +- got NACK for BSN=1247 +- got NACK for BSN=1248 +- got NACK for BSN=1249 +- got NACK for BSN=1250 +- got NACK for BSN=1251 +- got NACK for BSN=1252 +- got NACK for BSN=1253 +- got NACK for BSN=1254 +- got NACK for BSN=1255 +- got NACK for BSN=1256 +- got NACK for BSN=1257 +- got ack for BSN=1258 +- got ack for BSN=1259 +- got ack for BSN=1260 +- got NACK for BSN=1261 +- got ack for BSN=1262 +- got ack for BSN=1263 +- got ack for BSN=1264 +- got ack for BSN=1265 +- got ack for BSN=1266 +- got ack for BSN=1267 +- got ack for BSN=1268 +- got ack for BSN=1269 +- got ack for BSN=1270 +- got ack for BSN=1271 +- got ack for BSN=1272 +- got ack for BSN=1273 +- got ack for BSN=1274 +- got ack for BSN=1275 +- got ack for BSN=1276 +- got ack for BSN=1277 +- got ack for BSN=1278 +- got ack for BSN=1279 +- got ack for BSN=1280 +- got ack for BSN=1281 +- got ack for BSN=1282 +- got ack for BSN=1283 +- got ack for BSN=1284 +- got ack for BSN=1285 +- got ack for BSN=1286 +- got ack for BSN=1287 +- V(B): (V(A)=1186)"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAANAAAAAAAAAAAAAAAAAAAAAAAAAA"(V(S)-1=1287) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid +DL packet loss of IMSI= / TLLI=0xffeeddcc: 78% TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 20 09:46:09 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 09:46:09 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: Code-Review+1 Verified+1 -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 20 09:51:06 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 09:51:06 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: Hi Holger/Neels, As we have addressed all the comments raised. Can you please update the review status. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 20 12:02:21 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 12:02:21 +0000 Subject: osmo-pcu[master]: Fix slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 4: Hi Holger, >Starvation in the sense of always allocating the maximum and then not being >able to allocate a USF/UL TS to receive an answer from the phone? Starvation can be resolved with support of packet timeslot reconfigure with further improvement on polling. However we would like to know what number of MS you consider for starvation since we have tested this with 4 MS. >What is the argument of making it configurable? Do we expect a lot of >content producers trying to upload their podcast and want to have more UL >than DL timeslots? Patch was intended for maximizing slots allocation based on the DL capacity, so that 2 MS having same DL capacity gets same number of TS allocation. Since in current design only 1 TS is allocated for UL TBF, there will not be significance of maximizing UL allocation. Hence I will realign the patch accordingly. Thanks, Aravind Sirsikar -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 20 12:34:56 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Tue, 20 Sep 2016 12:34:56 +0000 Subject: [PATCH] osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/819 to look at the new patch set (#5). Fix: DL slot allocation based on direction configured Currently number of TS for second DL TBF is less compared to first DL TBF because PCU is considering the combined capacity of DL and UL for TS allocation, with this there is a difference in throughput between the 2 DL TBFs. This patch enables the user to maximize the number of DL TSs for the TBF based on the direction configured through VTY with cfg_pcu_ts_alloc_maximise_cmd Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 6 files changed, 52 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/5 diff --git a/src/bts.h b/src/bts.h index ba6fc4d..ff70b5f 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,10 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum maximise_direction { + DL_ONLY, + NO_MAXIMISE +}; struct BTS; struct GprsMs; @@ -191,6 +195,8 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + enum maximise_direction maximise_dir; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..6d451ff 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -775,9 +775,13 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) - continue; + if (bts->maximise_dir == DL_ONLY) { + if (rx_window < max_dl_slots) + continue; + } else { + if (capacity <= max_capacity) + continue; + } max_capacity = capacity; max_ul_slots = tx_window; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..c476726 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->maximise_dir = NO_MAXIMISE; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..8852935 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,32 @@ return CMD_SUCCESS; } +#define MAXIMISE_STR "Maximise TS allocation based on configuration\n" + +DEFUN(cfg_pcu_ts_alloc_maximise_type, + cfg_pcu_ts_alloc_maximise_cmd, + "maximise-direction dl", + MAXIMISE_STR "Maximise DL capacity\n") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->maximise_dir = DL_ONLY; + + return CMD_SUCCESS; +} + +DEFUN(cfg_pcu_no_maximise_direction, + cfg_pcu_no_maximise_direction_cmd, + "no maximise-direction", + NO_STR "Maximise direction configuration\n") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->maximise_dir = NO_MAXIMISE; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +998,8 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_ts_alloc_maximise_cmd); + install_element(PCU_NODE, &cfg_pcu_no_maximise_direction_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index f7794f7..0a97011 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->maximise_dir = NO_MAXIMISE; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -238,6 +240,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -285,6 +288,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[1].enable(); @@ -660,6 +664,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +703,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = NO_MAXIMISE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +812,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = DL_ONLY; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -830,13 +837,8 @@ if (dl_tbf2->pdch[i]) numTs2++; } - - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 == 4); tbf_free(dl_tbf1); tbf_free(dl_tbf2); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..9717411 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10795,4 +10795,4 @@ Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs TBF1: numTs(4) -TBF2: numTs(3) +TBF2: numTs(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Tue Sep 20 16:45:16 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 20 Sep 2016 16:45:16 +0000 Subject: [PATCH] libosmocore[master]: Fix ASAN failure in bitrev_test Message-ID: Review at https://gerrit.osmocom.org/863 Fix ASAN failure in bitrev_test Previously while testing osmo_nibble_shift_left_unal() following error was triggered by AddressSanitizer: ==3890== ERROR: AddressSanitizer: stack-buffer-overflow on address 0xbff5b5b6 at pc 0xb6186862 bp 0xbff5b4a8 sp 0xbff5b49c READ of size 1 at 0xbff5b5b6 thread T0 #0 0xb6186861 (/home/msuraev/source/gsm/libosmocore/src/.libs/libosmocore.so.7.0.0+0xc861) #1 0x8049d8b (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8049d8b) #2 0x804a9d1 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x804a9d1) #3 0xb5fe3af2 (/lib/i386-linux-gnu/libc-2.19.so+0x19af2) #4 0x8048a30 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8048a30) Address 0xbff5b5b6 is located at offset 38 in frame
of T0's stack: This frame has 3 object(s): [32, 38) 'in2' [96, 104) 'out' [160, 168) 'in1' The reason is incorrect range in test cycle. Fix it and adjust test output accordingly. Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Fixes: OW#1589 --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 1 insertion(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/63/863/1 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index 08f0827..59f173a 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -293,7 +293,7 @@ const uint8_t in1[] = { 0xF0, 0x0D, 0xCA, 0xFE, 0xDE, 0xAD, 0xBE, 0xEF }, in2[] = { 0xB0, 0x0B, 0xBA, 0xBE, 0xFA, 0xCE }; - for (offs = 0; offs < 13; offs++) { + for (offs = 0; offs < 12; offs++) { sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index 9fbb4d9..843a39a 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -150,11 +150,3 @@ OUT: 0b00bbabef [6] L IN: b00bbabeface, nibble 11: OUT: 00bbabefac -[8] R IN: f00dcafedeadbeef, nibble 12: - OUT: 0f00dcafedea -[8] L IN: f00dcafedeadbeef, nibble 12: - OUT: 00dcafedeadb -[6] R IN: b00bbabeface, nibble 12: - OUT: 0b00bbabefac -[6] L IN: b00bbabeface, nibble 12: - OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Sep 20 17:22:06 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 20 Sep 2016 17:22:06 +0000 Subject: [PATCH] libosmo-abis[master]: Use callback for polling data Message-ID: Review at https://gerrit.osmocom.org/864 Use callback for polling data Previously rs->rtp_bfd.when and rs->rtcp_bfd.when value of BSC_FD_READ was overridden by 0. Fix it. Reported by coverity: CID 1357763. Change-Id: I11940cbf50361c4ea262d7001a16f9a982392f27 --- M src/trau/osmo_ortp.c 1 file changed, 0 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/64/864/1 diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index cc1d748..0bb1197 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -218,7 +218,6 @@ rs->rtp_bfd.fd = rtp_session_get_rtp_socket(rs->sess); rs->rtcp_bfd.fd = rtp_session_get_rtcp_socket(rs->sess); rs->rtp_bfd.when = rs->rtcp_bfd.when = BSC_FD_READ; - rs->rtp_bfd.when = rs->rtcp_bfd.when = 0; rs->rtp_bfd.data = rs->rtcp_bfd.data = rs; rs->rtp_bfd.cb = osmo_rtp_fd_cb; rs->rtcp_bfd.cb = osmo_rtcp_fd_cb; -- To view, visit https://gerrit.osmocom.org/864 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I11940cbf50361c4ea262d7001a16f9a982392f27 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 21 16:12:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 16:12:45 +0000 Subject: libosmocore[master]: Fix ASAN failure in bitrev_test In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/863/1/tests/bits/bitrev_test.c File tests/bits/bitrev_test.c: Line 296: for (offs = 0; offs < 12; offs++) { Actually, only the last sh_chk should be omitted for offs == 12, the other three should still run. I have an alternative patch, will submit it shortly. Details: 'offs' should rather be called 'number_of_nibbles', and it goes up to 12 (< 13). in2 has exactly 12 nibbles. But to shift left, there needs to be one more nibble (i.e. byte) of data. So in2 has too few nibbles to shift left 12 nibbles. The other three cases have sufficient data to run with 12. -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 21 16:25:19 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 16:25:19 +0000 Subject: [PATCH] libosmocore[master]: Fix ASAN failure in bitrev_test In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/863 to look at the new patch set (#2). Fix ASAN failure in bitrev_test Previously while testing osmo_nibble_shift_left_unal() following error was triggered by AddressSanitizer upon offs == 12 and the last sh_chk line, i.e. shift left of 12 nibbles from in2: ==3890== ERROR: AddressSanitizer: stack-buffer-overflow on address 0xbff5b5b6 at pc 0xb6186862 bp 0xbff5b4a8 sp 0xbff5b49c READ of size 1 at 0xbff5b5b6 thread T0 #0 0xb6186861 (/home/msuraev/source/gsm/libosmocore/src/.libs/libosmocore.so.7.0.0+0xc861) #1 0x8049d8b (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8049d8b) #2 0x804a9d1 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x804a9d1) #3 0xb5fe3af2 (/lib/i386-linux-gnu/libc-2.19.so+0x19af2) #4 0x8048a30 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8048a30) Address 0xbff5b5b6 is located at offset 38 in frame
of T0's stack: This frame has 3 object(s): [32, 38) 'in2' [96, 104) 'out' [160, 168) 'in1' The reason is incorrect range in test cycle. Fix it and adjust test output accordingly. Tweaked-by: Neels Hofmeyr Fixes: OW#1589 ("undefined behavior in libosmocore triggered by tests") Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/63/863/2 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index 08f0827..b96241c 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -297,7 +297,9 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + /* in2 is too short to shift left 12 nibbles */ + if (offs < 12) + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index 9fbb4d9..e6f52af 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,5 +156,3 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac -[6] L IN: b00bbabeface, nibble 12: - OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 16:26:59 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 21 Sep 2016 16:26:59 +0000 Subject: libosmocore[master]: Fix ASAN failure in bitrev_test In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 21 16:33:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 16:33:00 +0000 Subject: [PATCH] libosmocore[master]: bitrev_test: don't omit last nibble from test result check Message-ID: Review at https://gerrit.osmocom.org/865 bitrev_test: don't omit last nibble from test result check The osmo_hexdump of the output in sh_chk() omitted the last byte of the osmo_nibble_shift_*() functions. Determine the number of bytes from nibbles divided by two plus one for any odd nibble number. Output this number of bytes of output data. Memset the output buffer to get well-defined bytes for unwritten places. Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 28 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/865/1 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index b96241c..ed3939a 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -208,6 +208,9 @@ static void sh_chk(const uint8_t *in, uint8_t len, unsigned int nib, bool r) { uint8_t x[len]; + int bytes = nib/2 + (nib & 1); + OSMO_ASSERT(len >= bytes); + memset(x, 0xcc, len); if (r) osmo_nibble_shift_right(x, in, nib); else @@ -217,7 +220,7 @@ osmo_hexdump_nospc(in, len), nib); /* do NOT combine those printfs: osmo_hexdump* use static buffer which WILL screw things up in that case */ - printf("\n OUT: %s\n", osmo_hexdump_nospc(x, nib/2)); + printf("\n OUT: %s\n", osmo_hexdump_nospc(x, bytes)); } int main(int argc, char **argv) diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index e6f52af..d2fb12c 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -63,13 +63,13 @@ [6] L IN: b00bbabeface, nibble 0: OUT: [8] R IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [8] L IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [6] R IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [6] L IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [8] R IN: f00dcafedeadbeef, nibble 2: OUT: 0f [8] L IN: f00dcafedeadbeef, nibble 2: @@ -79,13 +79,13 @@ [6] L IN: b00bbabeface, nibble 2: OUT: 00 [8] R IN: f00dcafedeadbeef, nibble 3: - OUT: 0f + OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 3: - OUT: 00 + OUT: 00d0 [6] R IN: b00bbabeface, nibble 3: - OUT: 0b + OUT: 0b00 [6] L IN: b00bbabeface, nibble 3: - OUT: 00 + OUT: 00b0 [8] R IN: f00dcafedeadbeef, nibble 4: OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 4: @@ -95,13 +95,13 @@ [6] L IN: b00bbabeface, nibble 4: OUT: 00bb [8] R IN: f00dcafedeadbeef, nibble 5: - OUT: 0f00 + OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 5: - OUT: 00dc + OUT: 00dca0 [6] R IN: b00bbabeface, nibble 5: - OUT: 0b00 + OUT: 0b00bb [6] L IN: b00bbabeface, nibble 5: - OUT: 00bb + OUT: 00bba0 [8] R IN: f00dcafedeadbeef, nibble 6: OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 6: @@ -111,13 +111,13 @@ [6] L IN: b00bbabeface, nibble 6: OUT: 00bbab [8] R IN: f00dcafedeadbeef, nibble 7: - OUT: 0f00dc + OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 7: - OUT: 00dcaf + OUT: 00dcafe0 [6] R IN: b00bbabeface, nibble 7: - OUT: 0b00bb + OUT: 0b00bbab [6] L IN: b00bbabeface, nibble 7: - OUT: 00bbab + OUT: 00bbabe0 [8] R IN: f00dcafedeadbeef, nibble 8: OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 8: @@ -127,13 +127,13 @@ [6] L IN: b00bbabeface, nibble 8: OUT: 00bbabef [8] R IN: f00dcafedeadbeef, nibble 9: - OUT: 0f00dcaf + OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 9: - OUT: 00dcafed + OUT: 00dcafede0 [6] R IN: b00bbabeface, nibble 9: - OUT: 0b00bbab + OUT: 0b00bbabef [6] L IN: b00bbabeface, nibble 9: - OUT: 00bbabef + OUT: 00bbabefa0 [8] R IN: f00dcafedeadbeef, nibble 10: OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 10: @@ -143,13 +143,13 @@ [6] L IN: b00bbabeface, nibble 10: OUT: 00bbabefac [8] R IN: f00dcafedeadbeef, nibble 11: - OUT: 0f00dcafed + OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 11: - OUT: 00dcafedea + OUT: 00dcafedead0 [6] R IN: b00bbabeface, nibble 11: - OUT: 0b00bbabef + OUT: 0b00bbabefac [6] L IN: b00bbabeface, nibble 11: - OUT: 00bbabefac + OUT: 00bbabeface0 [8] R IN: f00dcafedeadbeef, nibble 12: OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 12: -- To view, visit https://gerrit.osmocom.org/865 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 21:23:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 21:23:37 +0000 Subject: [PATCH] libosmocore[master]: bitrev_test: don't omit last byte from test result check In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/865 to look at the new patch set (#2). bitrev_test: don't omit last byte from test result check The osmo_hexdump of the output in sh_chk() omitted the last byte of the returned bytes from the osmo_nibble_shift_*() functions. Determine the number of bytes from nibbles divided by two plus one for any odd nibble number. Output this number of bytes of output data. Memset the output buffer to get well-defined bytes for unwritten places. Also assert that we have enough buffer length for all nibbles. Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 28 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/865/2 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index b96241c..ed3939a 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -208,6 +208,9 @@ static void sh_chk(const uint8_t *in, uint8_t len, unsigned int nib, bool r) { uint8_t x[len]; + int bytes = nib/2 + (nib & 1); + OSMO_ASSERT(len >= bytes); + memset(x, 0xcc, len); if (r) osmo_nibble_shift_right(x, in, nib); else @@ -217,7 +220,7 @@ osmo_hexdump_nospc(in, len), nib); /* do NOT combine those printfs: osmo_hexdump* use static buffer which WILL screw things up in that case */ - printf("\n OUT: %s\n", osmo_hexdump_nospc(x, nib/2)); + printf("\n OUT: %s\n", osmo_hexdump_nospc(x, bytes)); } int main(int argc, char **argv) diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index e6f52af..d2fb12c 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -63,13 +63,13 @@ [6] L IN: b00bbabeface, nibble 0: OUT: [8] R IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [8] L IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [6] R IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [6] L IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [8] R IN: f00dcafedeadbeef, nibble 2: OUT: 0f [8] L IN: f00dcafedeadbeef, nibble 2: @@ -79,13 +79,13 @@ [6] L IN: b00bbabeface, nibble 2: OUT: 00 [8] R IN: f00dcafedeadbeef, nibble 3: - OUT: 0f + OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 3: - OUT: 00 + OUT: 00d0 [6] R IN: b00bbabeface, nibble 3: - OUT: 0b + OUT: 0b00 [6] L IN: b00bbabeface, nibble 3: - OUT: 00 + OUT: 00b0 [8] R IN: f00dcafedeadbeef, nibble 4: OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 4: @@ -95,13 +95,13 @@ [6] L IN: b00bbabeface, nibble 4: OUT: 00bb [8] R IN: f00dcafedeadbeef, nibble 5: - OUT: 0f00 + OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 5: - OUT: 00dc + OUT: 00dca0 [6] R IN: b00bbabeface, nibble 5: - OUT: 0b00 + OUT: 0b00bb [6] L IN: b00bbabeface, nibble 5: - OUT: 00bb + OUT: 00bba0 [8] R IN: f00dcafedeadbeef, nibble 6: OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 6: @@ -111,13 +111,13 @@ [6] L IN: b00bbabeface, nibble 6: OUT: 00bbab [8] R IN: f00dcafedeadbeef, nibble 7: - OUT: 0f00dc + OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 7: - OUT: 00dcaf + OUT: 00dcafe0 [6] R IN: b00bbabeface, nibble 7: - OUT: 0b00bb + OUT: 0b00bbab [6] L IN: b00bbabeface, nibble 7: - OUT: 00bbab + OUT: 00bbabe0 [8] R IN: f00dcafedeadbeef, nibble 8: OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 8: @@ -127,13 +127,13 @@ [6] L IN: b00bbabeface, nibble 8: OUT: 00bbabef [8] R IN: f00dcafedeadbeef, nibble 9: - OUT: 0f00dcaf + OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 9: - OUT: 00dcafed + OUT: 00dcafede0 [6] R IN: b00bbabeface, nibble 9: - OUT: 0b00bbab + OUT: 0b00bbabef [6] L IN: b00bbabeface, nibble 9: - OUT: 00bbabef + OUT: 00bbabefa0 [8] R IN: f00dcafedeadbeef, nibble 10: OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 10: @@ -143,13 +143,13 @@ [6] L IN: b00bbabeface, nibble 10: OUT: 00bbabefac [8] R IN: f00dcafedeadbeef, nibble 11: - OUT: 0f00dcafed + OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 11: - OUT: 00dcafedea + OUT: 00dcafedead0 [6] R IN: b00bbabeface, nibble 11: - OUT: 0b00bbabef + OUT: 0b00bbabefac [6] L IN: b00bbabeface, nibble 11: - OUT: 00bbabefac + OUT: 00bbabeface0 [8] R IN: f00dcafedeadbeef, nibble 12: OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 12: -- To view, visit https://gerrit.osmocom.org/865 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:14:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:14:32 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs after build is done Message-ID: Review at https://gerrit.osmocom.org/866 jenkins.sh: output all test logs after build is done Add cat_testlogs.sh, call from jenkins.sh Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- A contrib/cat_testlogs.sh M contrib/jenkins.sh 2 files changed, 15 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/1 diff --git a/contrib/cat_testlogs.sh b/contrib/cat_testlogs.sh new file mode 100755 index 0000000..d2baef2 --- /dev/null +++ b/contrib/cat_testlogs.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set +x +find . -path "*/testsuite.dir/*/testsuite.log" | while read testlog; do + echo + echo + echo + echo ======================== "$testlog" + echo + cat $testlog +done + +# this will be called after a test failure, so make sure to return an error +exit 1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..6bc5461 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,4 +5,5 @@ autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || ./contrib/cat_testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:20:21 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:20:21 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs after build is done In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/866 to look at the new patch set (#2). jenkins.sh: output all test logs after build is done Add cat_testlogs.sh, call from jenkins.sh Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- A contrib/cat_testlogs.sh M contrib/jenkins.sh 2 files changed, 23 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/2 diff --git a/contrib/cat_testlogs.sh b/contrib/cat_testlogs.sh new file mode 100755 index 0000000..0d34a18 --- /dev/null +++ b/contrib/cat_testlogs.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Intended for use in jenkins build jobs, like this: +# $MAKE check || ./contrib/cat_testlogs.sh +# +# In the jenkins console output, show the actual failures by printing the test +# logs to the console output. This way we can see how exactly the test failed +# even if a job is older and no workspace is available. + +set +x +find . -path "*/testsuite.dir/*/testsuite.log" | while read testlog; do + echo + echo + echo + echo ======================== "$testlog" + echo + cat $testlog +done + +# this will be called after a test failure, so make sure to return an error +exit 1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..6bc5461 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,4 +5,5 @@ autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || ./contrib/cat_testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:20:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:20:22 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... Message-ID: Review at https://gerrit.osmocom.org/867 NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation Change-Id: Iffdb2351ad27dad809b21a14a08c14c0ffa3f9be --- M tests/a5/a5_test.ok 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/67/867/1 diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok index cefcdb6..9f7f9c3 100644 --- a/tests/a5/a5_test.ok +++ b/tests/a5/a5_test.ok @@ -10,6 +10,13 @@ A5/3 - UL: 001001010000100100000011011110001110000001010100000001000101011111000101011111100011011001110110011000101110010001 => OK A5/3 - DL: 000011100100000000010101011101010101101000110011011001000110100111000011110111011000011010000000111000110000001101 => OK A5/3 - UL: 011011110001000001100110100111100010101101001110000110001011000001000010010000110001101000101000111001000111111110 => OK + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + A5/3 - DL: 101010110111110110110011100010100101011100111010001100100101110110101010011101101110010011001011100000000000101001 => OK A5/3 - UL: 010011000100101101011001010011111110101010011101000000001111111010001001011110001011011110110111101111000001000010 => OK A5/3 - DL: 011101011111011111000100110001010001010101100000100100000101110111111011101000000101111001000110111110110101010011 => OK -- To view, visit https://gerrit.osmocom.org/867 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iffdb2351ad27dad809b21a14a08c14c0ffa3f9be Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:24:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:24:03 +0000 Subject: [ABANDON] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation ...................................................................... Abandoned testrun successful -- To view, visit https://gerrit.osmocom.org/867 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Iffdb2351ad27dad809b21a14a08c14c0ffa3f9be Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:34:53 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:34:53 +0000 Subject: [PATCH] osmo-iuh[master]: jenkins.sh: cat all test logs when build failed Message-ID: Review at https://gerrit.osmocom.org/868 jenkins.sh: cat all test logs when build failed Add cat_testlogs.sh, call from jenkins.sh Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae --- A contrib/cat_testlogs.sh M contrib/jenkins.sh 2 files changed, 25 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/68/868/1 diff --git a/contrib/cat_testlogs.sh b/contrib/cat_testlogs.sh new file mode 100755 index 0000000..0d34a18 --- /dev/null +++ b/contrib/cat_testlogs.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Intended for use in jenkins build jobs, like this: +# $MAKE check || ./contrib/cat_testlogs.sh +# +# In the jenkins console output, show the actual failures by printing the test +# logs to the console output. This way we can see how exactly the test failed +# even if a job is older and no workspace is available. + +set +x +find . -path "*/testsuite.dir/*/testsuite.log" | while read testlog; do + echo + echo + echo + echo ======================== "$testlog" + echo + cat $testlog +done + +# this will be called after a test failure, so make sure to return an error +exit 1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 8021bbd..85f2147 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -74,5 +74,7 @@ fi $MAKE $PARALLEL_MAKE -LD_LIBRARY_PATH="$inst/lib" $MAKE check -LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck +LD_LIBRARY_PATH="$inst/lib" $MAKE check \ + || ./contrib/cat_testlogs.sh +LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck \ + || ./contrib/cat_testlogs.sh -- To view, visit https://gerrit.osmocom.org/868 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:57:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:57:48 +0000 Subject: [PATCH] buildserver-commons[master]: add osmo-deps.sh Message-ID: Review at https://gerrit.osmocom.org/869 add osmo-deps.sh Taken from osmobuild1:/usr/local/bin Change-Id: Ib7ba98bb4f8a48745dd7a70883cb895595e71f7a --- A osmo-deps.sh 1 file changed, 10 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/buildserver-commons refs/changes/69/869/1 diff --git a/osmo-deps.sh b/osmo-deps.sh new file mode 100755 index 0000000..95081bd --- /dev/null +++ b/osmo-deps.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if ! test -d $1; +then + git clone git://git.osmocom.org/$1 $1 +fi + +cd $1 +git fetch origin +git reset --hard origin/master -- To view, visit https://gerrit.osmocom.org/869 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib7ba98bb4f8a48745dd7a70883cb895595e71f7a Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:57:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:57:48 +0000 Subject: [PATCH] buildserver-commons[master]: add cat_testlogs.sh Message-ID: Review at https://gerrit.osmocom.org/870 add cat_testlogs.sh To call from jenkins.sh: output all test logs when a build failed like make check || cat_testlogs.sh Change-Id: Ie3ad9513c1a2a493bac9d2b543c7736c01e34dfa --- A cat_testlogs.sh 1 file changed, 21 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/buildserver-commons refs/changes/70/870/1 diff --git a/cat_testlogs.sh b/cat_testlogs.sh new file mode 100755 index 0000000..0d34a18 --- /dev/null +++ b/cat_testlogs.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Intended for use in jenkins build jobs, like this: +# $MAKE check || ./contrib/cat_testlogs.sh +# +# In the jenkins console output, show the actual failures by printing the test +# logs to the console output. This way we can see how exactly the test failed +# even if a job is older and no workspace is available. + +set +x +find . -path "*/testsuite.dir/*/testsuite.log" | while read testlog; do + echo + echo + echo + echo ======================== "$testlog" + echo + cat $testlog +done + +# this will be called after a test failure, so make sure to return an error +exit 1 -- To view, visit https://gerrit.osmocom.org/870 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie3ad9513c1a2a493bac9d2b543c7736c01e34dfa Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:58:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:58:15 +0000 Subject: buildserver-commons[master]: add osmo-deps.sh In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 -- To view, visit https://gerrit.osmocom.org/869 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib7ba98bb4f8a48745dd7a70883cb895595e71f7a Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:58:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:58:22 +0000 Subject: buildserver-commons[master]: add cat_testlogs.sh In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 -- To view, visit https://gerrit.osmocom.org/870 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie3ad9513c1a2a493bac9d2b543c7736c01e34dfa Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:58:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:58:28 +0000 Subject: [MERGED] buildserver-commons[master]: add cat_testlogs.sh In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: add cat_testlogs.sh ...................................................................... add cat_testlogs.sh To call from jenkins.sh: output all test logs when a build failed like make check || cat_testlogs.sh Change-Id: Ie3ad9513c1a2a493bac9d2b543c7736c01e34dfa --- A cat_testlogs.sh 1 file changed, 21 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved; Verified diff --git a/cat_testlogs.sh b/cat_testlogs.sh new file mode 100755 index 0000000..0d34a18 --- /dev/null +++ b/cat_testlogs.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Intended for use in jenkins build jobs, like this: +# $MAKE check || ./contrib/cat_testlogs.sh +# +# In the jenkins console output, show the actual failures by printing the test +# logs to the console output. This way we can see how exactly the test failed +# even if a job is older and no workspace is available. + +set +x +find . -path "*/testsuite.dir/*/testsuite.log" | while read testlog; do + echo + echo + echo + echo ======================== "$testlog" + echo + cat $testlog +done + +# this will be called after a test failure, so make sure to return an error +exit 1 -- To view, visit https://gerrit.osmocom.org/870 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie3ad9513c1a2a493bac9d2b543c7736c01e34dfa Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Wed Sep 21 22:58:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 22:58:28 +0000 Subject: [MERGED] buildserver-commons[master]: add osmo-deps.sh In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: add osmo-deps.sh ...................................................................... add osmo-deps.sh Taken from osmobuild1:/usr/local/bin Change-Id: Ib7ba98bb4f8a48745dd7a70883cb895595e71f7a --- A osmo-deps.sh 1 file changed, 10 insertions(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved; Verified diff --git a/osmo-deps.sh b/osmo-deps.sh new file mode 100755 index 0000000..95081bd --- /dev/null +++ b/osmo-deps.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if ! test -d $1; +then + git clone git://git.osmocom.org/$1 $1 +fi + +cd $1 +git fetch origin +git reset --hard origin/master -- To view, visit https://gerrit.osmocom.org/869 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib7ba98bb4f8a48745dd7a70883cb895595e71f7a Gerrit-PatchSet: 1 Gerrit-Project: buildserver-commons Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Wed Sep 21 23:15:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 23:15:45 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs when build failed In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/866 to look at the new patch set (#3). jenkins.sh: output all test logs when build failed Assume that cat-testlogs.sh from buildserver-commons is in the PATH, and call from jenkins.sh upon 'make check' failure. Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- M contrib/jenkins.sh 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/3 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e5e17c8 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,4 +5,5 @@ autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 21 23:21:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 23:21:33 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... Message-ID: Review at https://gerrit.osmocom.org/871 NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac --- M tests/a5/a5_test.ok 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/71/871/1 diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok index cefcdb6..9f7f9c3 100644 --- a/tests/a5/a5_test.ok +++ b/tests/a5/a5_test.ok @@ -10,6 +10,13 @@ A5/3 - UL: 001001010000100100000011011110001110000001010100000001000101011111000101011111100011011001110110011000101110010001 => OK A5/3 - DL: 000011100100000000010101011101010101101000110011011001000110100111000011110111011000011010000000111000110000001101 => OK A5/3 - UL: 011011110001000001100110100111100010101101001110000110001011000001000010010000110001101000101000111001000111111110 => OK + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + A5/3 - DL: 101010110111110110110011100010100101011100111010001100100101110110101010011101101110010011001011100000000000101001 => OK A5/3 - UL: 010011000100101101011001010011111110101010011101000000001111111010001001011110001011011110110111101111000001000010 => OK A5/3 - DL: 011101011111011111000100110001010001010101100000100100000101110111111011101000000101111001000110111110110101010011 => OK -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 21 23:49:24 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 21 Sep 2016 23:49:24 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/871 to look at the new patch set (#2). NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac --- M contrib/jenkins.sh M tests/a5/a5_test.ok 2 files changed, 10 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/71/871/2 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e5e17c8..2916a57 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash +ls /usr/local/src + set -ex autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE $MAKE distcheck \ - || cat-testlogs.sh + || /usr/local/src/buildserver-commons/cat-testlogs.sh diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok index cefcdb6..9f7f9c3 100644 --- a/tests/a5/a5_test.ok +++ b/tests/a5/a5_test.ok @@ -10,6 +10,13 @@ A5/3 - UL: 001001010000100100000011011110001110000001010100000001000101011111000101011111100011011001110110011000101110010001 => OK A5/3 - DL: 000011100100000000010101011101010101101000110011011001000110100111000011110111011000011010000000111000110000001101 => OK A5/3 - UL: 011011110001000001100110100111100010101101001110000110001011000001000010010000110001101000101000111001000111111110 => OK + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + A5/3 - DL: 101010110111110110110011100010100101011100111010001100100101110110101010011101101110010011001011100000000000101001 => OK A5/3 - UL: 010011000100101101011001010011111110101010011101000000001111111010001001011110001011011110110111101111000001000010 => OK A5/3 - DL: 011101011111011111000100110001010001010101100000100100000101110111111011101000000101111001000110111110110101010011 => OK -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 00:03:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 00:03:42 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/871 to look at the new patch set (#3). NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac --- M contrib/jenkins.sh M tests/a5/a5_test.ok 2 files changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/71/871/3 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e5e17c8..1a772ee 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +ls /usr/local/src + set -ex autoreconf --install --force diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok index cefcdb6..9f7f9c3 100644 --- a/tests/a5/a5_test.ok +++ b/tests/a5/a5_test.ok @@ -10,6 +10,13 @@ A5/3 - UL: 001001010000100100000011011110001110000001010100000001000101011111000101011111100011011001110110011000101110010001 => OK A5/3 - DL: 000011100100000000010101011101010101101000110011011001000110100111000011110111011000011010000000111000110000001101 => OK A5/3 - UL: 011011110001000001100110100111100010101101001110000110001011000001000010010000110001101000101000111001000111111110 => OK + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + A5/3 - DL: 101010110111110110110011100010100101011100111010001100100101110110101010011101101110010011001011100000000000101001 => OK A5/3 - UL: 010011000100101101011001010011111110101010011101000000001111111010001001011110001011011110110111101111000001000010 => OK A5/3 - DL: 011101011111011111000100110001010001010101100000100100000101110111111011101000000101111001000110111110110101010011 => OK -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:10:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:10:31 +0000 Subject: [PATCH] libosmocore[master]: osmo_select_main(): drop useless call to osmo_timers_check() Message-ID: Review at https://gerrit.osmocom.org/872 osmo_select_main(): drop useless call to osmo_timers_check() osmo_timers_check() does nothing more than counting the active timers. It is of no use to count them when not using the return value in any way. Change-Id: I8d35ca90a4c16d6f1c7f9793d663e5479783efed --- M src/select.c 1 file changed, 0 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/72/872/1 diff --git a/src/select.c b/src/select.c index 192cae2..da27368 100644 --- a/src/select.c +++ b/src/select.c @@ -176,8 +176,6 @@ /* prepare read and write fdsets */ osmo_fd_fill_fds(&readset, &writeset, &exceptset); - osmo_timers_check(); - if (!polling) osmo_timers_prepare(); rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : osmo_timers_nearest()); -- To view, visit https://gerrit.osmocom.org/872 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8d35ca90a4c16d6f1c7f9793d663e5479783efed Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:07 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:07 +0000 Subject: [PATCH] libosmocore[master]: fix timer_test: don't forget to set tv_usec on the stop time Message-ID: Review at https://gerrit.osmocom.org/882 fix timer_test: don't forget to set tv_usec on the stop time The timer_test schedules timers and records the desired stop time. Also store the usec value of the desired stop time, because scheduling at e.g. sec N usec 999999 but recording sec N usec 0, and then receiving a timer at sec N+1 usec 0 is only 1 usec late, but records as 1000000 usecs late. This might have been the main cause of the timer test not working well on the osmocom build server. Change-Id: I13bb60f7d341a397f95d13d9c63c40188b6cd5a0 --- M tests/timer/timer_test.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/82/882/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 6184f66..4981fd5 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -95,6 +95,7 @@ v->timer.data = v; unsigned int seconds = (random() % 10) + 1; v->stop.tv_sec = v->start.tv_sec + seconds; + v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); } -- To view, visit https://gerrit.osmocom.org/882 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I13bb60f7d341a397f95d13d9c63c40188b6cd5a0 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:07 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:07 +0000 Subject: [PATCH] libosmocore[master]: timer_test: also report early finishes, report timing on error Message-ID: Review at https://gerrit.osmocom.org/883 timer_test: also report early finishes, report timing on error When a timer was late, show the timing details. Also count whether timers fired early, for completeness' sake. Change-Id: Id3942637d77a28b5092ffffcc3e6d9d67c2b8e68 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 19 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/883/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 4981fd5..c576a04 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -67,6 +67,7 @@ static unsigned int expired_timers = 0; static unsigned int total_timers = 0; static unsigned int too_late = 0; +static unsigned int too_soon = 0; static void main_timer_fired(void *data) { @@ -115,17 +116,30 @@ timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { - fprintf(stderr, "ERROR: timer %p has expired too late!\n", - &v->timer); + fprintf(stderr, "ERROR: timer has expired too late:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec + ); too_late++; + } + else if (timercmp(¤t, &v->stop, <)) { + fprintf(stderr, "ERROR: timer has expired too soon:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec + ); + too_soon++; } llist_del(&v->head); talloc_free(data); expired_timers++; if (expired_timers == total_timers) { - fprintf(stdout, "test over: added=%u expired=%u too_late=%u \n", - total_timers, expired_timers, too_late); + fprintf(stdout, "test over: added=%u expired=%u too_soon=%u too_late=%u\n", + total_timers, expired_timers, too_soon, too_late); exit(EXIT_SUCCESS); } diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 1bb382e..7c00000 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,2 @@ Running timer test for 5 steps, accepting imprecision of 0.020000 seconds -test over: added=31 expired=31 too_late=0 +test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/883 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id3942637d77a28b5092ffffcc3e6d9d67c2b8e68 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:07 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:07 +0000 Subject: [PATCH] libosmocore[master]: timer_test: remove unused precision values and confusing log Message-ID: Review at https://gerrit.osmocom.org/884 timer_test: remove unused precision values and confusing log Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 2 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/884/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index c576a04..7f5f58c 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,9 +59,6 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 -/* timer imprecision that we accept for this test: 10 milliseconds. */ -#define TIMER_PRES_SECS 0 -#define TIMER_PRES_USECS 20000 static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; @@ -185,9 +182,7 @@ } } - fprintf(stdout, "Running timer test for %u steps, accepting " - "imprecision of %u.%.6u seconds\n", - timer_nsteps, TIMER_PRES_SECS, TIMER_PRES_USECS); + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 7c00000..22b93aa 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,2 @@ -Running timer test for 5 steps, accepting imprecision of 0.020000 seconds +Running timer test for 5 steps test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/884 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:07 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:07 +0000 Subject: [PATCH] libosmocore[master]: add osmo_gettimeofday as a shim around gettimeofday Message-ID: Review at https://gerrit.osmocom.org/885 add osmo_gettimeofday as a shim around gettimeofday This allows feeding a custom time for unit tests by overriding osmo_gettimeofday. Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 --- M include/osmocom/core/timer.h M src/Makefile.am M src/gb/gprs_bssgp.c M src/gb/gprs_ns.c M src/logging.c M src/timer.c A src/timer_gettimeofday.c M src/vty/command.c M tests/gb/bssgp_fc_test.c M tests/timer/timer_test.c 10 files changed, 86 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/85/885/1 diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 6730bfe..dbda13f 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -29,6 +29,7 @@ #pragma once #include +#include #include #include @@ -83,4 +84,14 @@ int osmo_timers_update(void); int osmo_timers_check(void); +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz); + +/** + * timer override + */ + +extern bool osmo_gettimeofday_override; +extern struct timeval osmo_gettimeofday_override_time; +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs); + /*! @} */ diff --git a/src/Makefile.am b/src/Makefile.am index 7a6f464..74bdb21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = libosmocore.la libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) -libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \ +libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \ bitvec.c bitcomp.c statistics.c fsm.c \ write_queue.c utils.c socket.c \ logging.c logging_syslog.c rate_ctr.c \ diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 3ad2f29..1ee942f 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -603,7 +603,7 @@ fc->queue_depth--; /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; /* call the output callback for this FC instance */ @@ -688,7 +688,7 @@ /* compute number of centi-seconds that have elapsed since transmitting * the last PDU (Tc - Tp) */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); timersub(&time_now, &fc->time_last_pdu, &time_diff); csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000; @@ -747,7 +747,7 @@ return fc_enqueue(fc, msg, llc_pdu_len, priv); } else { /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; return fc->out_cb(priv, msg, llc_pdu_len, NULL); } @@ -766,7 +766,7 @@ fc->bucket_leak_rate = bucket_leak_rate; fc->max_queue_depth = max_queue_depth; INIT_LLIST_HEAD(&fc->queue); - gettimeofday(&fc->time_last_pdu, NULL); + osmo_gettimeofday(&fc->time_last_pdu, NULL); } /* Initialize the Flow Control parameters for a new MS according to diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 6879c70..18845d4 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -556,7 +556,7 @@ if (osmo_timer_pending(&nsvc->timer)) osmo_timer_del(&nsvc->timer); - gettimeofday(&nsvc->timer_started, NULL); + osmo_gettimeofday(&nsvc->timer_started, NULL); nsvc->timer_mode = mode; osmo_timer_schedule(&nsvc->timer, seconds, 0); } @@ -564,7 +564,7 @@ static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc) { struct timeval now, elapsed; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &nsvc->timer_started, &elapsed); return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000; diff --git a/src/logging.c b/src/logging.c index 8a10133..7c88b3d 100644 --- a/src/logging.c +++ b/src/logging.c @@ -268,7 +268,7 @@ if (target->print_ext_timestamp) { struct tm tm; struct timeval tv; - gettimeofday(&tv, NULL); + osmo_gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &tm); ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, diff --git a/src/timer.c b/src/timer.c index 0358b89..10a0b95 100644 --- a/src/timer.c +++ b/src/timer.c @@ -91,7 +91,7 @@ { struct timeval current_time; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); timer->timeout.tv_sec = seconds; timer->timeout.tv_usec = microseconds; timeradd(&timer->timeout, ¤t_time, &timer->timeout); @@ -143,7 +143,7 @@ struct timeval current_time; if (!now) - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); else current_time = *now; @@ -193,7 +193,7 @@ struct rb_node *node; struct timeval current; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); node = rb_first(&timer_root); if (node) { @@ -214,7 +214,7 @@ struct osmo_timer_list *this; int work = 0; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); INIT_LLIST_HEAD(&timer_eviction_list); for (node = rb_first(&timer_root); node; node = rb_next(node)) { diff --git a/src/timer_gettimeofday.c b/src/timer_gettimeofday.c new file mode 100644 index 0000000..e4106b6 --- /dev/null +++ b/src/timer_gettimeofday.c @@ -0,0 +1,58 @@ +/* + * (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Authors: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/*! \addtogroup timer + * @{ + */ + +/*! \file timer_gettimeofday.c + */ + +#include +#include + +bool osmo_gettimeofday_override = false; +struct timeval osmo_gettimeofday_override_time = { 23, 424242 }; + +/*! \brief shim around gettimeofday to be able to set the time manually. + * To override, set osmo_gettimeofday_override == true and set the desired + * current time in osmo_gettimeofday_override_time. */ +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + if (osmo_gettimeofday_override) { + *tv = osmo_gettimeofday_override_time; + return 0; + } + + return gettimeofday(tv, tz); +} + +/*! \brief convenience function to advance the fake time. + * Add the given values to osmo_gettimeofday_override_time. */ +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs) +{ + struct timeval val = { secs, usecs }; + timeradd(&osmo_gettimeofday_override_time, &val, + &osmo_gettimeofday_override_time); +} + +/*! @} */ diff --git a/src/vty/command.c b/src/vty/command.c index 483ca80..9d8bf31 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -637,7 +637,7 @@ struct timeval tv; char *crypt(const char *, const char *); - gettimeofday(&tv, 0); + osmo_gettimeofday(&tv, 0); to64(&salt[0], random(), 3); to64(&salt[3], tv.tv_usec, 3); diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c index ad8f83d..d77f141 100644 --- a/tests/gb/bssgp_fc_test.c +++ b/tests/gb/bssgp_fc_test.c @@ -22,7 +22,7 @@ { struct timeval tv; struct timeval now; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &tv_start, &tv); @@ -73,7 +73,7 @@ bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth, fc_out_cb); - gettimeofday(&tv_start, NULL); + osmo_gettimeofday(&tv_start, NULL); for (i = 0; i < pdu_count; i++) { fc_in(fc, pdu_len); diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 7f5f58c..6fbd0a3 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -88,7 +88,7 @@ fprintf(stderr, "timer_test: OOM!\n"); return; } - gettimeofday(&v->start, NULL); + osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; unsigned int seconds = (random() % 10) + 1; @@ -109,7 +109,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res, precision = { 1, 0 }; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { -- To view, visit https://gerrit.osmocom.org/885 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:08 +0000 Subject: [PATCH] libosmocore[master]: timer_test: do not use real time: deterministic and faster Message-ID: Review at https://gerrit.osmocom.org/886 timer_test: do not use real time: deterministic and faster Use osmo_gettimeofday_override* to decouple the timer test from real time. No longer call osmo_select_main(), since select() actually waits for real time. This reduces the timer_test to the osmo_timer_* logic and excludes the real time and osmo_timers_nearest() accuracy testing with actual waiting involved. This may be seen as a loss, but is more fit for a test suite. The main point here is to get deterministic results in jenkins, so that we don't have to retrigger jobs based on timing failures; added bonus is that the test runs much faster now. Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 --- M tests/timer/timer_test.c 1 file changed, 14 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/86/886/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 6fbd0a3..461d060 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,6 +59,8 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 +/* how much time elapses between checks, in microsecs */ +#define TIME_BETWEEN_TIMER_CHECKS 423210 static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; @@ -107,7 +109,8 @@ static void secondary_timer_fired(void *data) { struct test_timer *v = data, *this, *tmp; - struct timeval current, res, precision = { 1, 0 }; + struct timeval current, res; + struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; osmo_gettimeofday(¤t, NULL); @@ -151,21 +154,12 @@ } } -static void alarm_handler(int signum) -{ - fprintf(stderr, "ERROR: We took too long to run the timer test, " - "something seems broken, aborting.\n"); - exit(EXIT_FAILURE); -} - int main(int argc, char *argv[]) { int c; + int steps; - if (signal(SIGALRM, alarm_handler) == SIG_ERR) { - perror("cannot register signal handler"); - exit(EXIT_FAILURE); - } + osmo_gettimeofday_override = true; while ((c = getopt_long(argc, argv, "s:", NULL, NULL)) != -1) { switch(c) { @@ -182,21 +176,21 @@ } } + steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) + / TIME_BETWEEN_TIMER_CHECKS; + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); - /* if the test takes too long, we may consider that the timer scheduler - * has hung. We set some maximum wait time which is the double of the - * maximum timeout randomly set (10 seconds, worst case) plus the - * number of steps (since some of them are reset each step). */ - alarm(2 * (10 + timer_nsteps)); - #ifdef HAVE_SYS_SELECT_H - while (1) { - osmo_select_main(0); + while (steps--) { + osmo_timers_prepare(); + osmo_timers_update(); + osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); } #else fprintf(stdout, "Select not supported on this platform!\n"); #endif + return 0; } -- To view, visit https://gerrit.osmocom.org/886 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:08 +0000 Subject: [PATCH] libosmocore[master]: timer_test: remove all random elements Message-ID: Review at https://gerrit.osmocom.org/887 timer_test: remove all random elements Change-Id: I9833031407e99f5d7a1144c26b68a7e320b2020d --- M tests/timer/timer_test.c 1 file changed, 6 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/87/887/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 461d060..d8e1ec9 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -93,7 +93,7 @@ osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; - unsigned int seconds = (random() % 10) + 1; + unsigned int seconds = (i & 0x7) + 1; v->stop.tv_sec = v->start.tv_sec + seconds; v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); @@ -111,6 +111,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res; struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; + int i; osmo_gettimeofday(¤t, NULL); @@ -143,9 +144,11 @@ exit(EXIT_SUCCESS); } - /* randomly (10%) deletion of timers. */ + /* "random" deletion of timers. */ + i = 0; llist_for_each_entry_safe(this, tmp, &timer_test_list, head) { - if ((random() % 100) < 10) { + i ++; + if (!(i & 0x3)) { osmo_timer_del(&this->timer); llist_del(&this->head); talloc_free(this); -- To view, visit https://gerrit.osmocom.org/887 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9833031407e99f5d7a1144c26b68a7e320b2020d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:08 +0000 Subject: [PATCH] libosmocore[master]: timer_test: redirect some output from stderr to stdout Message-ID: Review at https://gerrit.osmocom.org/888 timer_test: redirect some output from stderr to stdout This way we can check the output in timer_test.ok. Change-Id: Ia3bba1c650be3558d370e0f59d4ee7f36ef97506 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 24 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/88/888/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index d8e1ec9..12caecf 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -75,8 +75,8 @@ int i; if (*step == timer_nsteps) { - fprintf(stderr, "Main timer has finished, please, " - "wait a bit for the final report.\n"); + printf("Main timer has finished, please, " + "wait a bit for the final report.\n"); return; } /* add 2^step pair of timers per step. */ @@ -87,7 +87,7 @@ v = talloc_zero(NULL, struct test_timer); if (v == NULL) { - fprintf(stderr, "timer_test: OOM!\n"); + printf("timer_test: OOM!\n"); return; } osmo_gettimeofday(&v->start, NULL); @@ -99,7 +99,7 @@ osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); } - fprintf(stderr, "added %d timers in step %u (expired=%u)\n", + printf("added %d timers in step %u (expired=%u)\n", add_in_this_step, *step, expired_timers); total_timers += add_in_this_step; osmo_timer_schedule(&main_timer, TIME_BETWEEN_STEPS, 0); @@ -117,21 +117,19 @@ timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { - fprintf(stderr, "ERROR: timer has expired too late:" - " wanted %d.%06d now %d.%06d diff %d.%06d\n", - (int)v->stop.tv_sec, (int)v->stop.tv_usec, - (int)current.tv_sec, (int)current.tv_usec, - (int)res.tv_sec, (int)res.tv_usec - ); + printf("ERROR: timer has expired too late:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); too_late++; } else if (timercmp(¤t, &v->stop, <)) { - fprintf(stderr, "ERROR: timer has expired too soon:" - " wanted %d.%06d now %d.%06d diff %d.%06d\n", - (int)v->stop.tv_sec, (int)v->stop.tv_usec, - (int)current.tv_sec, (int)current.tv_usec, - (int)res.tv_sec, (int)res.tv_usec - ); + printf("ERROR: timer has expired too soon:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); too_soon++; } @@ -139,8 +137,8 @@ talloc_free(data); expired_timers++; if (expired_timers == total_timers) { - fprintf(stdout, "test over: added=%u expired=%u too_soon=%u too_late=%u\n", - total_timers, expired_timers, too_soon, too_late); + printf("test over: added=%u expired=%u too_soon=%u too_late=%u\n", + total_timers, expired_timers, too_soon, too_late); exit(EXIT_SUCCESS); } @@ -182,7 +180,7 @@ steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) / TIME_BETWEEN_TIMER_CHECKS; - fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); + printf("Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); @@ -193,7 +191,7 @@ osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); } #else - fprintf(stdout, "Select not supported on this platform!\n"); + printf("Select not supported on this platform!\n"); #endif return 0; } diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 22b93aa..7617bc3 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,8 @@ Running timer test for 5 steps +added 1 timers in step 0 (expired=0) +added 2 timers in step 1 (expired=0) +added 4 timers in step 2 (expired=1) +added 8 timers in step 3 (expired=4) +added 16 timers in step 4 (expired=7) +Main timer has finished, please, wait a bit for the final report. test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/888 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia3bba1c650be3558d370e0f59d4ee7f36ef97506 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:08 +0000 Subject: [PATCH] libosmocore[master]: timer_test: print more details to stdout to check Message-ID: Review at https://gerrit.osmocom.org/889 timer_test: print more details to stdout to check The test is now fully deterministic, so include all detail in stdout, to check for. Change-Id: Iecf6387f1d25253fcf1260777673853030c1d326 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 116 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/89/889/1 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 12caecf..ec85c04 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -73,6 +73,7 @@ unsigned int *step = data; unsigned int add_in_this_step; int i; + printf("main_timer_fired()\n"); if (*step == timer_nsteps) { printf("Main timer has finished, please, " @@ -98,6 +99,8 @@ v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); + printf("scheduled timer at %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec); } printf("added %d timers in step %u (expired=%u)\n", add_in_this_step, *step, expired_timers); @@ -111,7 +114,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res; struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; - int i; + int i, deleted; osmo_gettimeofday(¤t, NULL); @@ -132,6 +135,10 @@ (int)res.tv_sec, (int)res.tv_usec); too_soon++; } + else + printf("timer fired on time: %d.%06d (+ %d.%06d)\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); llist_del(&v->head); talloc_free(data); @@ -144,15 +151,19 @@ /* "random" deletion of timers. */ i = 0; + deleted = 0; llist_for_each_entry_safe(this, tmp, &timer_test_list, head) { i ++; if (!(i & 0x3)) { osmo_timer_del(&this->timer); llist_del(&this->head); talloc_free(this); - expired_timers++; + deleted++; } } + expired_timers += deleted; + printf("early deleted %d timers, %d still active\n", deleted, + total_timers - expired_timers); } int main(int argc, char *argv[]) @@ -180,12 +191,16 @@ steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) / TIME_BETWEEN_TIMER_CHECKS; - printf("Running timer test for %u steps\n", timer_nsteps); + printf("Running timer test for %d iterations," + " %d steps of %d msecs each\n", + timer_nsteps, steps, TIME_BETWEEN_TIMER_CHECKS / 1000); osmo_timer_schedule(&main_timer, 1, 0); #ifdef HAVE_SYS_SELECT_H while (steps--) { + printf("%d.%06d\n", (int)osmo_gettimeofday_override_time.tv_sec, + (int)osmo_gettimeofday_override_time.tv_usec); osmo_timers_prepare(); osmo_timers_update(); osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 7617bc3..109d039 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,8 +1,105 @@ -Running timer test for 5 steps +Running timer test for 5 iterations, 85 steps of 423 msecs each +23.424242 +23.847452 +24.270662 +24.693872 +main_timer_fired() +scheduled timer at 25.693872 added 1 timers in step 0 (expired=0) +25.117082 +25.540292 +25.963502 +main_timer_fired() +scheduled timer at 26.963502 +scheduled timer at 27.963502 added 2 timers in step 1 (expired=0) +timer fired on time: 25.693872 (+ 0.269630) +early deleted 0 timers, 2 still active +26.386712 +26.809922 +27.233132 +main_timer_fired() +scheduled timer at 28.233132 +scheduled timer at 29.233132 +scheduled timer at 30.233132 +scheduled timer at 31.233132 added 4 timers in step 2 (expired=1) +timer fired on time: 26.963502 (+ 0.269630) +early deleted 1 timers, 4 still active +27.656342 +28.079552 +timer fired on time: 27.963502 (+ 0.116050) +early deleted 0 timers, 3 still active +28.502762 +main_timer_fired() +scheduled timer at 29.502762 +scheduled timer at 30.502762 +scheduled timer at 31.502762 +scheduled timer at 32.502762 +scheduled timer at 33.502762 +scheduled timer at 34.502762 +scheduled timer at 35.502762 +scheduled timer at 36.502762 added 8 timers in step 3 (expired=4) +28.925972 +29.349182 +timer fired on time: 29.233132 (+ 0.116050) +early deleted 2 timers, 8 still active +29.772392 +main_timer_fired() +scheduled timer at 30.772392 +scheduled timer at 31.772392 +scheduled timer at 32.772392 +scheduled timer at 33.772392 +scheduled timer at 34.772392 +scheduled timer at 35.772392 +scheduled timer at 36.772392 +scheduled timer at 37.772392 +scheduled timer at 30.772392 +scheduled timer at 31.772392 +scheduled timer at 32.772392 +scheduled timer at 33.772392 +scheduled timer at 34.772392 +scheduled timer at 35.772392 +scheduled timer at 36.772392 +scheduled timer at 37.772392 added 16 timers in step 4 (expired=7) +30.195602 +30.618812 +timer fired on time: 30.502762 (+ 0.116050) +early deleted 5 timers, 18 still active +timer fired on time: 30.233132 (+ 0.385680) +early deleted 4 timers, 13 still active +31.042022 +main_timer_fired() Main timer has finished, please, wait a bit for the final report. +31.465232 +timer fired on time: 31.233132 (+ 0.232100) +early deleted 3 timers, 9 still active +31.888442 +timer fired on time: 31.772392 (+ 0.116050) +early deleted 2 timers, 6 still active +32.311652 +32.734862 +33.158072 +timer fired on time: 32.772392 (+ 0.385680) +early deleted 1 timers, 4 still active +33.581282 +34.004492 +34.427702 +34.850912 +35.274122 +35.697332 +36.120542 +timer fired on time: 35.772392 (+ 0.348150) +early deleted 0 timers, 3 still active +36.543752 +timer fired on time: 36.502762 (+ 0.040990) +early deleted 0 timers, 2 still active +36.966962 +timer fired on time: 36.772392 (+ 0.194570) +early deleted 0 timers, 1 still active +37.390172 +37.813382 +timer fired on time: 37.772392 (+ 0.040990) test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/889 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iecf6387f1d25253fcf1260777673853030c1d326 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:33:08 +0000 Subject: [PATCH] libosmocore[master]: timer_test: set 8 as default steps, use the default in tests... Message-ID: Review at https://gerrit.osmocom.org/890 timer_test: set 8 as default steps, use the default in testsuite.at Change-Id: I5070578e9fe2bdacaad000eaafb8dc5f549d6f3e --- M tests/testsuite.at M tests/timer/timer_test.c M tests/timer/timer_test.ok 3 files changed, 281 insertions(+), 16 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/90/890/1 diff --git a/tests/testsuite.at b/tests/testsuite.at index 0c7edf1..2f274f9 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -193,7 +193,7 @@ AT_SETUP([timer]) AT_KEYWORDS([timer]) cat $abs_srcdir/timer/timer_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/timer/timer_test -s 5], [0], [expout], [ignore]) +AT_CHECK([$abs_top_builddir/tests/timer/timer_test], [0], [expout], [ignore]) AT_CLEANUP AT_SETUP([tlv]) diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index ec85c04..066dc72 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -54,7 +54,7 @@ }; /* number of test steps. We add fact(steps) timers in the whole test. */ -#define MAIN_TIMER_NSTEPS 16 +#define MAIN_TIMER_NSTEPS 8 /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 109d039..75b11c7 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,4 +1,4 @@ -Running timer test for 5 iterations, 85 steps of 423 msecs each +Running timer test for 8 iterations, 66 steps of 423 msecs each 23.424242 23.847452 24.270662 @@ -72,34 +72,299 @@ early deleted 4 timers, 13 still active 31.042022 main_timer_fired() -Main timer has finished, please, wait a bit for the final report. +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +added 32 timers in step 5 (expired=18) 31.465232 timer fired on time: 31.233132 (+ 0.232100) -early deleted 3 timers, 9 still active +early deleted 11 timers, 33 still active 31.888442 timer fired on time: 31.772392 (+ 0.116050) -early deleted 2 timers, 6 still active +early deleted 8 timers, 24 still active 32.311652 +main_timer_fired() +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +added 64 timers in step 6 (expired=39) 32.734862 33.158072 -timer fired on time: 32.772392 (+ 0.385680) -early deleted 1 timers, 4 still active +timer fired on time: 33.042022 (+ 0.116050) +early deleted 21 timers, 66 still active +timer fired on time: 33.042022 (+ 0.116050) +early deleted 16 timers, 49 still active 33.581282 +main_timer_fired() +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +added 128 timers in step 7 (expired=78) 34.004492 34.427702 +timer fired on time: 34.311652 (+ 0.116050) +early deleted 44 timers, 132 still active +timer fired on time: 34.311652 (+ 0.116050) +early deleted 32 timers, 99 still active +timer fired on time: 34.311652 (+ 0.116050) +early deleted 24 timers, 74 still active 34.850912 +main_timer_fired() +Main timer has finished, please, wait a bit for the final report. 35.274122 35.697332 +timer fired on time: 35.581282 (+ 0.116050) +early deleted 18 timers, 55 still active +timer fired on time: 35.581282 (+ 0.116050) +early deleted 13 timers, 41 still active +timer fired on time: 35.581282 (+ 0.116050) +early deleted 10 timers, 30 still active 36.120542 -timer fired on time: 35.772392 (+ 0.348150) -early deleted 0 timers, 3 still active 36.543752 -timer fired on time: 36.502762 (+ 0.040990) -early deleted 0 timers, 2 still active +timer fired on time: 36.311652 (+ 0.232100) +early deleted 7 timers, 22 still active +timer fired on time: 36.311652 (+ 0.232100) +early deleted 5 timers, 16 still active 36.966962 -timer fired on time: 36.772392 (+ 0.194570) -early deleted 0 timers, 1 still active +timer fired on time: 36.581282 (+ 0.385680) +early deleted 3 timers, 12 still active 37.390172 +timer fired on time: 37.042022 (+ 0.348150) +early deleted 2 timers, 9 still active 37.813382 -timer fired on time: 37.772392 (+ 0.040990) -test over: added=31 expired=31 too_soon=0 too_late=0 +timer fired on time: 37.581282 (+ 0.232100) +early deleted 2 timers, 6 still active +38.236592 +38.659802 +39.083012 +39.506222 +timer fired on time: 39.311652 (+ 0.194570) +early deleted 1 timers, 4 still active +39.929432 +timer fired on time: 39.581282 (+ 0.348150) +early deleted 0 timers, 3 still active +40.352642 +40.775852 +timer fired on time: 40.581282 (+ 0.194570) +early deleted 0 timers, 2 still active +41.199062 +41.622272 +timer fired on time: 41.581282 (+ 0.040990) +early deleted 0 timers, 1 still active +timer fired on time: 41.581282 (+ 0.040990) +test over: added=255 expired=255 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/890 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5070578e9fe2bdacaad000eaafb8dc5f549d6f3e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:41:40 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:41:40 +0000 Subject: libosmocore[master]: remove unused local variable in get_rate_ctr() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/860 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:41:50 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:41:50 +0000 Subject: libosmocore[master]: remove unused function get_rate_ctr_group() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/859 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:41:53 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:41:53 +0000 Subject: [MERGED] libosmocore[master]: remove unused function get_rate_ctr_group() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: remove unused function get_rate_ctr_group() ...................................................................... remove unused function get_rate_ctr_group() Unused after 22886d9e320ecf734d2827d825a191b977f70d2c "Fix retrieving rate_ctr over control interface" Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e --- M src/ctrl/control_if.c 1 file changed, 0 insertions(+), 37 deletions(-) Approvals: Max: Looks good to me, but someone else must approve Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 6d9a9fb..228fe35 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -448,43 +448,6 @@ return counters; } -static int get_rate_ctr_group(const char *ctr_group, int intv, struct ctrl_cmd *cmd) -{ - int i; - char *counters; - struct rate_ctr_group *ctrg; - - cmd->reply = talloc_asprintf(cmd, "All counters in group %s", ctr_group); - if (!cmd->reply) - goto oom; - - for (i=0;;i++) { - ctrg = rate_ctr_get_group_by_name_idx(ctr_group, i); - if (!ctrg) - break; - - counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); - if (!counters) - goto oom; - - cmd->reply = talloc_asprintf_append(cmd->reply, "%s", counters); - talloc_free(counters); - if (!cmd->reply) - goto oom; - } - - /* We found no counter group by that name */ - if (i == 0) { - cmd->reply = talloc_asprintf(cmd, "No counter group with name %s.", ctr_group); - return CTRL_CMD_ERROR; - } - - return CTRL_CMD_REPLY; -oom: - cmd->reply = "OOM."; - return CTRL_CMD_ERROR; -} - static int get_rate_ctr_group_idx(const struct rate_ctr_group *ctrg, int intv, struct ctrl_cmd *cmd) { char *counters; -- To view, visit https://gerrit.osmocom.org/859 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I405367ef6ba5833957778a79dd398ce5ea29307e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:41:56 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:41:56 +0000 Subject: [MERGED] libosmocore[master]: remove unused local variable in get_rate_ctr() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: remove unused local variable in get_rate_ctr() ...................................................................... remove unused local variable in get_rate_ctr() Unused after 22886d9e320ecf734d2827d825a191b977f70d2c "Fix retrieving rate_ctr over control interface" Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 --- M src/ctrl/control_if.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Max: Looks good to me, but someone else must approve Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 228fe35..05f6c76 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -474,7 +474,7 @@ { int intv; unsigned int idx; - char *ctr_group, *ctr_idx, *ctr_name, *tmp, *dup, *saveptr, *interval; + char *ctr_group, *ctr_idx, *tmp, *dup, *saveptr, *interval; struct rate_ctr_group *ctrg; const struct rate_ctr *ctr; -- To view, visit https://gerrit.osmocom.org/860 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib5411da80c4eb4f905a5ed87c60477eca2cdff42 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 04:50:21 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 04:50:21 +0000 Subject: [PATCH] libosmocore[master]: add osmo_gettimeofday as a shim around gettimeofday In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/885 to look at the new patch set (#2). add osmo_gettimeofday as a shim around gettimeofday This allows feeding a custom time for unit tests by overriding osmo_gettimeofday. Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 --- M include/osmocom/core/timer.h M src/Makefile.am M src/gb/gprs_bssgp.c M src/gb/gprs_ns.c M src/logging.c M src/timer.c A src/timer_gettimeofday.c M src/vty/command.c M tests/gb/bssgp_fc_test.c M tests/timer/timer_test.c 10 files changed, 87 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/85/885/2 diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 6730bfe..dbda13f 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -29,6 +29,7 @@ #pragma once #include +#include #include #include @@ -83,4 +84,14 @@ int osmo_timers_update(void); int osmo_timers_check(void); +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz); + +/** + * timer override + */ + +extern bool osmo_gettimeofday_override; +extern struct timeval osmo_gettimeofday_override_time; +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs); + /*! @} */ diff --git a/src/Makefile.am b/src/Makefile.am index 7a6f464..74bdb21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = libosmocore.la libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) -libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \ +libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \ bitvec.c bitcomp.c statistics.c fsm.c \ write_queue.c utils.c socket.c \ logging.c logging_syslog.c rate_ctr.c \ diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 3ad2f29..1ee942f 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -603,7 +603,7 @@ fc->queue_depth--; /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; /* call the output callback for this FC instance */ @@ -688,7 +688,7 @@ /* compute number of centi-seconds that have elapsed since transmitting * the last PDU (Tc - Tp) */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); timersub(&time_now, &fc->time_last_pdu, &time_diff); csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000; @@ -747,7 +747,7 @@ return fc_enqueue(fc, msg, llc_pdu_len, priv); } else { /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; return fc->out_cb(priv, msg, llc_pdu_len, NULL); } @@ -766,7 +766,7 @@ fc->bucket_leak_rate = bucket_leak_rate; fc->max_queue_depth = max_queue_depth; INIT_LLIST_HEAD(&fc->queue); - gettimeofday(&fc->time_last_pdu, NULL); + osmo_gettimeofday(&fc->time_last_pdu, NULL); } /* Initialize the Flow Control parameters for a new MS according to diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 6879c70..18845d4 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -556,7 +556,7 @@ if (osmo_timer_pending(&nsvc->timer)) osmo_timer_del(&nsvc->timer); - gettimeofday(&nsvc->timer_started, NULL); + osmo_gettimeofday(&nsvc->timer_started, NULL); nsvc->timer_mode = mode; osmo_timer_schedule(&nsvc->timer, seconds, 0); } @@ -564,7 +564,7 @@ static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc) { struct timeval now, elapsed; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &nsvc->timer_started, &elapsed); return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000; diff --git a/src/logging.c b/src/logging.c index 8a10133..9e30d5f 100644 --- a/src/logging.c +++ b/src/logging.c @@ -44,6 +44,7 @@ #include #include #include +#include #include /* for LOGGING_STR. */ @@ -268,7 +269,7 @@ if (target->print_ext_timestamp) { struct tm tm; struct timeval tv; - gettimeofday(&tv, NULL); + osmo_gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &tm); ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, diff --git a/src/timer.c b/src/timer.c index 0358b89..10a0b95 100644 --- a/src/timer.c +++ b/src/timer.c @@ -91,7 +91,7 @@ { struct timeval current_time; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); timer->timeout.tv_sec = seconds; timer->timeout.tv_usec = microseconds; timeradd(&timer->timeout, ¤t_time, &timer->timeout); @@ -143,7 +143,7 @@ struct timeval current_time; if (!now) - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); else current_time = *now; @@ -193,7 +193,7 @@ struct rb_node *node; struct timeval current; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); node = rb_first(&timer_root); if (node) { @@ -214,7 +214,7 @@ struct osmo_timer_list *this; int work = 0; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); INIT_LLIST_HEAD(&timer_eviction_list); for (node = rb_first(&timer_root); node; node = rb_next(node)) { diff --git a/src/timer_gettimeofday.c b/src/timer_gettimeofday.c new file mode 100644 index 0000000..e4106b6 --- /dev/null +++ b/src/timer_gettimeofday.c @@ -0,0 +1,58 @@ +/* + * (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Authors: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/*! \addtogroup timer + * @{ + */ + +/*! \file timer_gettimeofday.c + */ + +#include +#include + +bool osmo_gettimeofday_override = false; +struct timeval osmo_gettimeofday_override_time = { 23, 424242 }; + +/*! \brief shim around gettimeofday to be able to set the time manually. + * To override, set osmo_gettimeofday_override == true and set the desired + * current time in osmo_gettimeofday_override_time. */ +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + if (osmo_gettimeofday_override) { + *tv = osmo_gettimeofday_override_time; + return 0; + } + + return gettimeofday(tv, tz); +} + +/*! \brief convenience function to advance the fake time. + * Add the given values to osmo_gettimeofday_override_time. */ +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs) +{ + struct timeval val = { secs, usecs }; + timeradd(&osmo_gettimeofday_override_time, &val, + &osmo_gettimeofday_override_time); +} + +/*! @} */ diff --git a/src/vty/command.c b/src/vty/command.c index 483ca80..9d8bf31 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -637,7 +637,7 @@ struct timeval tv; char *crypt(const char *, const char *); - gettimeofday(&tv, 0); + osmo_gettimeofday(&tv, 0); to64(&salt[0], random(), 3); to64(&salt[3], tv.tv_usec, 3); diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c index ad8f83d..d77f141 100644 --- a/tests/gb/bssgp_fc_test.c +++ b/tests/gb/bssgp_fc_test.c @@ -22,7 +22,7 @@ { struct timeval tv; struct timeval now; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &tv_start, &tv); @@ -73,7 +73,7 @@ bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth, fc_out_cb); - gettimeofday(&tv_start, NULL); + osmo_gettimeofday(&tv_start, NULL); for (i = 0; i < pdu_count; i++) { fc_in(fc, pdu_len); diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 7f5f58c..6fbd0a3 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -88,7 +88,7 @@ fprintf(stderr, "timer_test: OOM!\n"); return; } - gettimeofday(&v->start, NULL); + osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; unsigned int seconds = (random() % 10) + 1; @@ -109,7 +109,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res, precision = { 1, 0 }; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { -- To view, visit https://gerrit.osmocom.org/885 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:00:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:00:32 +0000 Subject: [PATCH] libosmocore[master]: log telnet bind address and port Message-ID: Review at https://gerrit.osmocom.org/891 log telnet bind address and port Log 'telnet at 1.2.3.4 5678' from telnet_init*. All callers can now drop any extra 'VTY at 1.2.3.4 5678' logging. Change-Id: I1da7b9076311d9458caea732fc0daace6533a3fd --- M src/vty/telnet_interface.c 1 file changed, 8 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/91/891/1 diff --git a/src/vty/telnet_interface.c b/src/vty/telnet_interface.c index 50b08c8..e86a6b1 100644 --- a/src/vty/telnet_interface.c +++ b/src/vty/telnet_interface.c @@ -86,7 +86,14 @@ server_socket.data = priv; - return (rc < 0) ? -1 : 0; + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "Cannot bind telnet at %s %d\n", + ip, port); + return -1; + } + + LOGP(DLGLOBAL, LOGL_NOTICE, "telnet at %s %d\n", ip, port); + return 0; } extern struct host host; -- To view, visit https://gerrit.osmocom.org/891 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1da7b9076311d9458caea732fc0daace6533a3fd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:00:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:00:32 +0000 Subject: [PATCH] libosmocore[master]: log CTRL bind address and port Message-ID: Review at https://gerrit.osmocom.org/892 log CTRL bind address and port Log 'CTRL at 1.2.3.4 5678' from ctrl_interface_setup*. All callers can now drop any extra 'CTRL at 1.2.3.4 5678' logging. Change-Id: If449d0514e3d0cc1b346d7452194d931aa090166 --- M src/ctrl/control_if.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/92/892/1 diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 6d9a9fb..dcc0066 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -706,11 +706,14 @@ if (ret) goto err_vec; + LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; err_vec: vector_free(ctrl_node_vec); ctrl_node_vec = NULL; err: + LOGP(DLCTRL, LOGL_ERROR, "Cannot bind CTRL at %s %u\n", + bind_addr, port); talloc_free(ctrl); return NULL; } -- To view, visit https://gerrit.osmocom.org/892 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If449d0514e3d0cc1b346d7452194d931aa090166 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:05:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:05:01 +0000 Subject: [PATCH] osmo-bts[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/754 to look at the new patch set (#2). heed VTY 'line vty'/'bind' command Like most other osmo-* programs, bind the telnet VTY to the address specified by the 'line vty'/'bind' command. This is added by vty_init(), so until now the BTS offered this config but ignored it. Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d --- M src/common/main.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/54/754/2 diff --git a/src/common/main.c b/src/common/main.c index 5e0f1a1..99febe0 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -303,7 +303,8 @@ bts_controlif_setup(bts); - rc = telnet_init(tall_bts_ctx, NULL, g_vty_port_num); + rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(), + g_vty_port_num); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/754 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:07:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:07:02 +0000 Subject: [PATCH] osmo-pcu[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/753 to look at the new patch set (#2). heed VTY 'line vty'/'bind' command Like most other osmo-* programs, bind the telnet VTY to the address specified by the 'line vty'/'bind' command. This is added by vty_init(), so until now the PCU offered this config but ignored it. Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d --- M src/pcu_main.cpp 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/53/753/2 diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..4a75c79 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -251,7 +251,8 @@ fprintf(stderr, "No config file: '%s' Using default config.\n", config_file); - rc = telnet_init(tall_pcu_ctx, NULL, OSMO_VTY_PORT_PCU); + rc = telnet_init_dynif(tall_pcu_ctx, NULL, vty_get_bind_addr(), + OSMO_VTY_PORT_PCU); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:07:59 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:07:59 +0000 Subject: osmo-bts[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 2: see also #892 -- To view, visit https://gerrit.osmocom.org/754 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:10:52 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:10:52 +0000 Subject: [PATCH] libosmocore[master]: timer_test: remove unused precision values and confusing log In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/884 to look at the new patch set (#2). timer_test: remove unused precision values and confusing log Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 2 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/884/2 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index c576a04..1aeab45 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,10 +59,6 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 -/* timer imprecision that we accept for this test: 10 milliseconds. */ -#define TIMER_PRES_SECS 0 -#define TIMER_PRES_USECS 20000 - static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; static unsigned int total_timers = 0; @@ -185,9 +181,7 @@ } } - fprintf(stdout, "Running timer test for %u steps, accepting " - "imprecision of %u.%.6u seconds\n", - timer_nsteps, TIMER_PRES_SECS, TIMER_PRES_USECS); + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 7c00000..22b93aa 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,2 @@ -Running timer test for 5 steps, accepting imprecision of 0.020000 seconds +Running timer test for 5 steps test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/884 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:18:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:18:38 +0000 Subject: [PATCH] libosmocore[master]: add osmo_gettimeofday as a shim around gettimeofday In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/885 to look at the new patch set (#3). add osmo_gettimeofday as a shim around gettimeofday This allows feeding a custom time for unit tests by overriding osmo_gettimeofday. Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 --- M include/osmocom/core/timer.h M src/Makefile.am M src/gb/gprs_bssgp.c M src/gb/gprs_ns.c M src/logging.c M src/timer.c A src/timer_gettimeofday.c M src/vty/command.c M tests/gb/bssgp_fc_test.c M tests/timer/timer_test.c 10 files changed, 87 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/85/885/3 diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 6730bfe..dbda13f 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -29,6 +29,7 @@ #pragma once #include +#include #include #include @@ -83,4 +84,14 @@ int osmo_timers_update(void); int osmo_timers_check(void); +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz); + +/** + * timer override + */ + +extern bool osmo_gettimeofday_override; +extern struct timeval osmo_gettimeofday_override_time; +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs); + /*! @} */ diff --git a/src/Makefile.am b/src/Makefile.am index 7a6f464..74bdb21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = libosmocore.la libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) -libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \ +libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \ bitvec.c bitcomp.c statistics.c fsm.c \ write_queue.c utils.c socket.c \ logging.c logging_syslog.c rate_ctr.c \ diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 3ad2f29..1ee942f 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -603,7 +603,7 @@ fc->queue_depth--; /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; /* call the output callback for this FC instance */ @@ -688,7 +688,7 @@ /* compute number of centi-seconds that have elapsed since transmitting * the last PDU (Tc - Tp) */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); timersub(&time_now, &fc->time_last_pdu, &time_diff); csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000; @@ -747,7 +747,7 @@ return fc_enqueue(fc, msg, llc_pdu_len, priv); } else { /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; return fc->out_cb(priv, msg, llc_pdu_len, NULL); } @@ -766,7 +766,7 @@ fc->bucket_leak_rate = bucket_leak_rate; fc->max_queue_depth = max_queue_depth; INIT_LLIST_HEAD(&fc->queue); - gettimeofday(&fc->time_last_pdu, NULL); + osmo_gettimeofday(&fc->time_last_pdu, NULL); } /* Initialize the Flow Control parameters for a new MS according to diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 6879c70..18845d4 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -556,7 +556,7 @@ if (osmo_timer_pending(&nsvc->timer)) osmo_timer_del(&nsvc->timer); - gettimeofday(&nsvc->timer_started, NULL); + osmo_gettimeofday(&nsvc->timer_started, NULL); nsvc->timer_mode = mode; osmo_timer_schedule(&nsvc->timer, seconds, 0); } @@ -564,7 +564,7 @@ static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc) { struct timeval now, elapsed; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &nsvc->timer_started, &elapsed); return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000; diff --git a/src/logging.c b/src/logging.c index 8a10133..9e30d5f 100644 --- a/src/logging.c +++ b/src/logging.c @@ -44,6 +44,7 @@ #include #include #include +#include #include /* for LOGGING_STR. */ @@ -268,7 +269,7 @@ if (target->print_ext_timestamp) { struct tm tm; struct timeval tv; - gettimeofday(&tv, NULL); + osmo_gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &tm); ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, diff --git a/src/timer.c b/src/timer.c index 0358b89..10a0b95 100644 --- a/src/timer.c +++ b/src/timer.c @@ -91,7 +91,7 @@ { struct timeval current_time; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); timer->timeout.tv_sec = seconds; timer->timeout.tv_usec = microseconds; timeradd(&timer->timeout, ¤t_time, &timer->timeout); @@ -143,7 +143,7 @@ struct timeval current_time; if (!now) - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); else current_time = *now; @@ -193,7 +193,7 @@ struct rb_node *node; struct timeval current; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); node = rb_first(&timer_root); if (node) { @@ -214,7 +214,7 @@ struct osmo_timer_list *this; int work = 0; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); INIT_LLIST_HEAD(&timer_eviction_list); for (node = rb_first(&timer_root); node; node = rb_next(node)) { diff --git a/src/timer_gettimeofday.c b/src/timer_gettimeofday.c new file mode 100644 index 0000000..81a1598 --- /dev/null +++ b/src/timer_gettimeofday.c @@ -0,0 +1,58 @@ +/* + * (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Authors: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/*! \addtogroup timer + * @{ + */ + +/*! \file timer_gettimeofday.c + */ + +#include +#include + +bool osmo_gettimeofday_override = false; +struct timeval osmo_gettimeofday_override_time = { 23, 424242 }; + +/*! \brief shim around gettimeofday to be able to set the time manually. + * To override, set osmo_gettimeofday_override == true and set the desired + * current time in osmo_gettimeofday_override_time. */ +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + if (osmo_gettimeofday_override) { + *tv = osmo_gettimeofday_override_time; + return 0; + } + + return gettimeofday(tv, tz); +} + +/*! \brief convenience function to advance the fake time. + * Add the given values to osmo_gettimeofday_override_time. */ +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs) +{ + struct timeval val = { secs, usecs }; + timeradd(&osmo_gettimeofday_override_time, &val, + &osmo_gettimeofday_override_time); +} + +/*! @} */ diff --git a/src/vty/command.c b/src/vty/command.c index 483ca80..9d8bf31 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -637,7 +637,7 @@ struct timeval tv; char *crypt(const char *, const char *); - gettimeofday(&tv, 0); + osmo_gettimeofday(&tv, 0); to64(&salt[0], random(), 3); to64(&salt[3], tv.tv_usec, 3); diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c index ad8f83d..d77f141 100644 --- a/tests/gb/bssgp_fc_test.c +++ b/tests/gb/bssgp_fc_test.c @@ -22,7 +22,7 @@ { struct timeval tv; struct timeval now; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &tv_start, &tv); @@ -73,7 +73,7 @@ bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth, fc_out_cb); - gettimeofday(&tv_start, NULL); + osmo_gettimeofday(&tv_start, NULL); for (i = 0; i < pdu_count; i++) { fc_in(fc, pdu_len); diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 1aeab45..6308113 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -87,7 +87,7 @@ fprintf(stderr, "timer_test: OOM!\n"); return; } - gettimeofday(&v->start, NULL); + osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; unsigned int seconds = (random() % 10) + 1; @@ -108,7 +108,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res, precision = { 1, 0 }; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { -- To view, visit https://gerrit.osmocom.org/885 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 05:18:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 05:18:38 +0000 Subject: [PATCH] libosmocore[master]: timer_test: do not use real time: deterministic and faster In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/886 to look at the new patch set (#3). timer_test: do not use real time: deterministic and faster Use osmo_gettimeofday_override* to decouple the timer test from real time. No longer call osmo_select_main(), since select() actually waits for real time. This reduces the timer_test to the osmo_timer_* logic and excludes the real time and osmo_timers_nearest() accuracy testing with actual waiting involved. This may be seen as a loss, but is more fit for a test suite. The main point here is to get deterministic results in jenkins, so that we don't have to retrigger jobs based on timing failures; added bonus is that the test runs much faster now. Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 --- M tests/timer/timer_test.c 1 file changed, 15 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/86/886/3 diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 6308113..461d060 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,6 +59,9 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 +/* how much time elapses between checks, in microsecs */ +#define TIME_BETWEEN_TIMER_CHECKS 423210 + static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; static unsigned int total_timers = 0; @@ -106,7 +109,8 @@ static void secondary_timer_fired(void *data) { struct test_timer *v = data, *this, *tmp; - struct timeval current, res, precision = { 1, 0 }; + struct timeval current, res; + struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; osmo_gettimeofday(¤t, NULL); @@ -150,21 +154,12 @@ } } -static void alarm_handler(int signum) -{ - fprintf(stderr, "ERROR: We took too long to run the timer test, " - "something seems broken, aborting.\n"); - exit(EXIT_FAILURE); -} - int main(int argc, char *argv[]) { int c; + int steps; - if (signal(SIGALRM, alarm_handler) == SIG_ERR) { - perror("cannot register signal handler"); - exit(EXIT_FAILURE); - } + osmo_gettimeofday_override = true; while ((c = getopt_long(argc, argv, "s:", NULL, NULL)) != -1) { switch(c) { @@ -181,21 +176,21 @@ } } + steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) + / TIME_BETWEEN_TIMER_CHECKS; + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); - /* if the test takes too long, we may consider that the timer scheduler - * has hung. We set some maximum wait time which is the double of the - * maximum timeout randomly set (10 seconds, worst case) plus the - * number of steps (since some of them are reset each step). */ - alarm(2 * (10 + timer_nsteps)); - #ifdef HAVE_SYS_SELECT_H - while (1) { - osmo_select_main(0); + while (steps--) { + osmo_timers_prepare(); + osmo_timers_update(); + osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); } #else fprintf(stdout, "Select not supported on this platform!\n"); #endif + return 0; } -- To view, visit https://gerrit.osmocom.org/886 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 06:23:37 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 06:23:37 +0000 Subject: [ABANDON] libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 06:36:04 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 06:36:04 +0000 Subject: libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has restored this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 06:58:19 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 06:58:19 +0000 Subject: [ABANDON] libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 08:18:14 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 22 Sep 2016 08:18:14 +0000 Subject: libosmocore[master]: Add function to send TRAP over Control Interface In-Reply-To: References: Message-ID: Patch Set 2: Note: get_rate_ctr_group() has been dropped in gerrit #859. -- To view, visit https://gerrit.osmocom.org/649 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic0b8d88c4f5c4d42c3f8fb754f8eabf049c9e388 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 22 10:51:08 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 10:51:08 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Fixing missing payload type in ph. chan. activation Message-ID: Review at https://gerrit.osmocom.org/900 octphy: Fixing missing payload type in ph. chan. activation in l1_oml.c:ts_connect() the payload type (ulPayloadType) was not configured to full-rate for PDTCHF PACCHF and PTCCHF. Older octasic firmwares (below octsdr-2g-02.06.00-B964-alpha) will tolerate this, newer versions will crash during channel initalitation. Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/00/900/1 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index ed365b6..7735261 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1448,6 +1448,7 @@ * a TCH/H ? */ switch (oc->ulChannelType) { case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_TCHF_FACCHF_SACCHTF: + case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_PDTCHF_PACCHF_PTCCHF: oc->ulPayloadType = cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_FULL_RATE; break; case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_TCHH_FACCHH_SACCHTH: -- To view, visit https://gerrit.osmocom.org/900 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 12:35:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 12:35:57 +0000 Subject: [PATCH] osmo-bts[master]: measurement.c Message-ID: Review at https://gerrit.osmocom.org/901 measurement.c This was handed in by octasic. The particular purpose of this is unclear to me. Please leave a comment on how to proceed with this. Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 --- M src/common/measurement.c 1 file changed, 6 insertions(+), 50 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/01/901/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index be1d4f6..8c1012b 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -71,15 +71,11 @@ break; case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: - fn_mod = fn % 102; - if (fn_mod == 11) - rc = 1; + rc = 1; break; case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4_CBCH: - fn_mod = fn % 102; - if (fn_mod == 36) - rc = 1; + rc = 1; break; default: rc = 0; @@ -135,13 +131,6 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) { struct gsm_meas_rep_unidir *mru; - uint32_t ber_full_sum = 0; - uint32_t irssi_full_sum = 0; - uint32_t ber_sub_sum = 0; - uint32_t irssi_sub_sum = 0; - int32_t taqb_sum = 0; - unsigned int num_meas_sub = 0; - int i; /* if measurement period is not complete, abort */ if (!is_meas_complete(lchan->ts->pchan, lchan->ts->nr, @@ -152,45 +141,12 @@ if (lchan->meas.num_ul_meas == 0) return 0; - /* compute the actual measurements */ - - /* step 1: add up */ - for (i = 0; i < lchan->meas.num_ul_meas; i++) { - struct bts_ul_meas *m = &lchan->meas.uplink[i]; - - ber_full_sum += m->ber10k; - irssi_full_sum += m->inv_rssi; - taqb_sum += m->ta_offs_qbits; - - if (m->is_sub) { - num_meas_sub++; - ber_sub_sum += m->ber10k; - irssi_sub_sum += m->inv_rssi; - } - } - - /* step 2: divide */ - ber_full_sum = ber_full_sum / lchan->meas.num_ul_meas; - irssi_full_sum = irssi_full_sum / lchan->meas.num_ul_meas; - taqb_sum = taqb_sum / lchan->meas.num_ul_meas; - - if (num_meas_sub) { - ber_sub_sum = ber_sub_sum / num_meas_sub; - irssi_sub_sum = irssi_sub_sum / num_meas_sub; - } - - DEBUGP(DMEAS, "%s Computed TA(% 4dqb) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), " - "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", gsm_lchan_name(lchan), - taqb_sum, ber_full_sum/100, - ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100, - irssi_sub_sum); - /* store results */ mru = &lchan->meas.ul_res; - mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1); - mru->sub.rx_lev = dbm2rxlev((int)irssi_sub_sum * -1); - mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum); - mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum); + mru->full.rx_lev = lchan->meas.uplink[0].inv_rssi; + mru->sub.rx_lev = lchan->meas.uplink[0].inv_rssi; + mru->full.rx_qual = (uint8_t)lchan->meas.uplink[0].ber10k; + mru->sub.rx_qual = (uint8_t)lchan->meas.uplink[0].ber10k; lchan->meas.flags |= LC_UL_M_F_RES_VALID; lchan->meas.num_ul_meas = 0; -- To view, visit https://gerrit.osmocom.org/901 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 12:35:57 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 12:35:57 +0000 Subject: [PATCH] osmo-bts[master]: rsl: improved log output Message-ID: Review at https://gerrit.osmocom.org/902 rsl: improved log output improving the log output to show more details about the payload type and the connection Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd --- M src/common/rsl.c 1 file changed, 17 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/02/902/1 diff --git a/src/common/rsl.c b/src/common/rsl.c index 493ff3b..84938d3 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1429,13 +1429,13 @@ /* Connection ID */ msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, htons(lchan->abis_ip.conn_id)); - /* locally bound IP */ - msgb_v_put(msg, RSL_IE_IPAC_LOCAL_IP); - msgb_put_u32(msg, lchan->abis_ip.bound_ip); - /* locally bound port */ msgb_tv16_put(msg, RSL_IE_IPAC_LOCAL_PORT, lchan->abis_ip.bound_port); + + /* locally bound IP */ + msgb_v_put(msg, RSL_IE_IPAC_LOCAL_IP); + msgb_put_u32(msg, lchan->abis_ip.bound_ip); if (inc_pt2) { /* RTP Payload Type 2 */ @@ -1584,21 +1584,27 @@ return tx_ipac_XXcx_nack(lchan, RSL_ERR_MAND_IE_ERROR, 0, dch->c.msg_type); - /* any of these can be NULL!! */ - speech_mode = TLVP_VAL(&tp, RSL_IE_IPAC_SPEECH_MODE); - payload_type = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD); - payload_type2 = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD2); - - if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_IP)) + if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_IP)) { connect_ip = tlvp_val32_unal(&tp, RSL_IE_IPAC_REMOTE_IP); + LOGP(DRSL, LOGL_NOTICE, "connect_ip %d \n", connect_ip ); + } else LOGP(DRSL, LOGL_NOTICE, "CRCX does not specify a remote IP\n"); - if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_PORT)) + if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_PORT)) { connect_port = tlvp_val16_unal(&tp, RSL_IE_IPAC_REMOTE_PORT); + LOGP(DRSL, LOGL_NOTICE, "connect_port %d \n", connect_port ); + } else LOGP(DRSL, LOGL_NOTICE, "CRCX does not specify a remote port\n"); + /* any of these can be NULL!! */ + speech_mode = TLVP_VAL(&tp, RSL_IE_IPAC_SPEECH_MODE); + LOGP(DRSL, LOGL_NOTICE, "speech_mode %d \n",*speech_mode ); + payload_type = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD); + LOGP(DRSL, LOGL_NOTICE, "Pay load type %d \n",*payload_type ); + payload_type2 = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD2); + if (dch->c.msg_type == RSL_MT_IPAC_CRCX && connect_ip && connect_port) inc_ip_port = 1; -- To view, visit https://gerrit.osmocom.org/902 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 13:15:28 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 13:15:28 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Fixing band selection for ARFCN 0 Message-ID: Review at https://gerrit.osmocom.org/903 octphy: Fixing band selection for ARFCN 0 There is now an exception for ARFCN 0 in osmocom_to_octphy_band to distingush ARFCN 0 (E-GSM) and 1-124 (P-GSM). Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/03/903/1 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index d621bcf..d2d765f 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -98,7 +98,9 @@ case GSM_BAND_850: return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_850; case GSM_BAND_900: - if (arfcn >= 955 && arfcn <= 974) + if(arfcn == 0) + return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; + else if (arfcn >= 955 && arfcn <= 974) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_R_900; else if (arfcn >= 975 && arfcn <= 1023) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; -- To view, visit https://gerrit.osmocom.org/903 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 14:28:49 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 14:28:49 +0000 Subject: [PATCH] osmo-bts[master]: octphy: improved channel measurement Message-ID: Review at https://gerrit.osmocom.org/904 octphy: improved channel measurement Not entirely sure what problem this is fixing, depending on your comments here. Change-Id: Ib2de74e8ec6549f867ac0a04c554167b664ce9b6 --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 5 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/04/904/1 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index d2d765f..a567ba1 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -789,10 +789,10 @@ PRIM_OP_INDICATION, NULL); l1sap.u.info.type = PRIM_INFO_MEAS; l1sap.u.info.u.meas_ind.chan_nr = chan_nr; - l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming; + l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming4x; - l1sap.u.info.u.meas_ind.ber10k = (unsigned int)(m->usBERCnt * 100); - l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->sRSSIDbm * -1); + l1sap.u.info.u.meas_ind.ber10k = m->usRxQualFullUp; + l1sap.u.info.u.meas_ind.inv_rssi = m->usRxLevelFullUp; /* l1sap wants to take msgb ownership. However, as there is no * msg, it will msgb_free(l1sap.oph.msg == NULL) */ @@ -992,7 +992,8 @@ memset(&l1sap, 0, sizeof(l1sap)); /* uplink measurement */ - process_meas_res(trx, chan_nr, &data_ind->MeasurementInfo); + if(sapi == cOCTVC1_GSM_SAPI_ENUM_SACCH) + process_meas_res(trx, chan_nr, &data_ind->MeasurementInfo); /* FIXME: check min_qual_norm! */ -- To view, visit https://gerrit.osmocom.org/904 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib2de74e8ec6549f867ac0a04c554167b664ce9b6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 14:28:49 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 14:28:49 +0000 Subject: [PATCH] osmo-bts[master]: octphy: set tx attenuation via VTY Message-ID: Review at https://gerrit.osmocom.org/905 octphy: set tx attenuation via VTY add code to configure the transmision power via VTY Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 --- M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/octphy_vty.c 2 files changed, 22 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/05/905/1 diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index ea0fb33..7c09b2d 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -62,6 +62,7 @@ /* configuration */ uint32_t rf_port_index; uint32_t rx_gain_db; + uint32_t tx_atten_flag; uint32_t tx_atten_db; struct octphy_hdl *hdl; diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index 3ea576c..53099c8 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -135,6 +135,24 @@ return CMD_SUCCESS; } +DEFUN(cfg_phy_tx_atten_flag, cfg_phy_tx_atten_flag_cmd, + "octphy tx-attenuation-flag <0-1>", + OCT_STR "1 - Use config file to set Tx Attenuation\n" + "Use config file to set Tx Attenuation\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.tx_atten_flag = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_phy_tx_atten_db, cfg_phy_tx_atten_db_cmd, "octphy tx-attenuation <0-359>", OCT_STR "Configure the Tx Attenuation in quarter-dB\n" @@ -202,6 +220,8 @@ VTY_NEWLINE); vty_out(vty, " rx-gain %u%s", plink->u.octphy.rx_gain_db, VTY_NEWLINE); + vty_out(vty, " tx-attenuation-flag %u%s", plink->u.octphy.tx_atten_flag, + VTY_NEWLINE); vty_out(vty, " tx-attenuation %u%s", plink->u.octphy.tx_atten_db, VTY_NEWLINE); vty_out(vty, " rf-port-index %u%s", plink->u.octphy.rf_port_index, @@ -250,6 +270,7 @@ install_element(PHY_NODE, &cfg_phy_netdev_cmd); install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); + install_element(PHY_NODE, &cfg_phy_tx_atten_flag_cmd); install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); install_element_ve(&show_rf_port_stats_cmd); -- To view, visit https://gerrit.osmocom.org/905 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 14:28:49 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 14:28:49 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Fixed OML ADM state handling Message-ID: Review at https://gerrit.osmocom.org/906 octphy: Fixed OML ADM state handling bts_model_chg_adm_state() is accepting all state changes blindly, this patch adds a proper state handling Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 79 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/06/906/1 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 7735261..f8c5ac9 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -50,6 +50,8 @@ #include #include +int trx_locked = 0; + /* Map OSMOCOM logical channel type to OctPHY Logical channel type */ static tOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM pchan_to_logChComb[_GSM_PCHAN_MAX] = { @@ -1349,7 +1351,14 @@ oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; /* FIXME: compute this based on nominal transmit power, etc. */ - oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + if(plink->u.octphy.tx_atten_flag == 1) { + oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + } + else { + /* Take the Tx Attn received in set radio attribures + * x4 is for the value in db */ + oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; + } LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "tsc=%u, rx_gain=%u, tx_atten=%u)\n", @@ -1502,10 +1511,75 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state) { - /* TODO: implement this properly */ - /* blindly accept all state changes */ - mo->nm_state.administrative = adm_state; - return oml_mo_statechg_ack(mo); + int rc; + int granted = 0; + + struct gsm_bts_trx *trx; + struct phy_instance *pinst; + struct octphy_hdl *fl1h; + + switch (mo->obj_class) { + case NM_OC_RADIO_CARRIER: + + trx = ((struct gsm_bts_trx *)obj); + pinst = trx_phy_instance(trx); + fl1h = pinst->phy_link->u.octphy.hdl; + + if (mo->procedure_pending) { + LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: " + "pending procedure on RC %d\n", trx->nr); + return 0; + } + mo->procedure_pending = 1; + switch (adm_state) { + case NM_STATE_LOCKED: + + trx_locked = 1; + + /* Stop heartbeat check */ + osmo_timer_del(&fl1h->alive_timer); + + bts_model_trx_deact_rf(trx); + + /* Close TRX */ + rc = bts_model_trx_close(trx); + if (rc != 0) { + LOGP(DL1C, LOGL_ERROR, + "TRX already closed..!\n\n"); + } + granted = 1; + break; + + case NM_STATE_UNLOCKED: + + if (trx_locked) { + trx_locked = 0; + l1if_activate_rf(trx, 1); + } + + granted = 1; + break; + + default: + granted = 1; + break; + } + + mo->procedure_pending = 0; + break; + + default: + /* blindly accept all state changes */ + granted = 1; + break; + } + + if (granted) { + mo->nm_state.administrative = adm_state; + return oml_mo_statechg_ack(mo); + } else + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) -- To view, visit https://gerrit.osmocom.org/906 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 15:09:59 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 22 Sep 2016 15:09:59 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Dont't crash if transceiver is re-initalized Message-ID: Review at https://gerrit.osmocom.org/907 octphy: Dont't crash if transceiver is re-initalized An already opend TRX would cause osmo-bts to exit, this patch handels the condition gracefully. Same is true in case of already activated physical channels Change-Id: I3fccc8e45843d255b256a753547436c39bbf38b0 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 21 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/07/907/1 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index f8c5ac9..8d707f4 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1307,11 +1307,15 @@ trx->nr, octvc1_rc2string(or->Header.ulReturnCode)); /* FIXME: check for ulReturnCode == OK */ - if (or->Header.ulReturnCode != cOCTVC1_RC_OK) { - LOGP(DL1C, LOGL_ERROR, "TRX-OPEN failed: %s\n", - octvc1_rc2string(or->Header.ulReturnCode)); - msgb_free(resp); - exit(1); + if (or->Header.ulReturnCode != cOCTVC1_RC_OK) + { + if(or->Header.ulReturnCode != cOCTVC1_GSM_RC_TRX_ALREADY_OPENED) + { + LOGP(DL1C, LOGL_ERROR, "TRX-OPEN failed: %s\n", + octvc1_rc2string(or->Header.ulReturnCode)); + msgb_free(resp); + exit(1); + } } msgb_free(resp); @@ -1327,8 +1331,7 @@ octphy_hw_get_clock_sync_info(fl1h); fl1h->opened = 1; - /* Temporary fix for enabling events after TRX Close + Reopen */ - return l1if_enable_events(trx); + return 0; } int l1if_trx_open(struct gsm_bts_trx *trx) @@ -1419,13 +1422,17 @@ ts->trx->nr, ts->nr, ts->pchan, octvc1_rc2string(ar->Header.ulReturnCode)); - if (ar->Header.ulReturnCode != cOCTVC1_RC_OK) { - LOGP(DL1C, LOGL_ERROR, - "PCHAN-ACT failed: %s\n\n", - octvc1_rc2string(ar->Header.ulReturnCode)); - LOGP(DL1C, LOGL_ERROR, "Exiting... \n\n"); - msgb_free(resp); - exit(-1); + if (ar->Header.ulReturnCode != cOCTVC1_RC_OK) + { + if(ar->Header.ulReturnCode != cOCTVC1_GSM_RC_PHYSICAL_CHANNEL_ALREADY_ACTIVATED) + { + LOGP(DL1C, LOGL_ERROR, + "PCHAN-ACT failed: %s\n\n", + octvc1_rc2string(ar->Header.ulReturnCode)); + LOGP(DL1C, LOGL_ERROR, "Exiting... \n\n"); + msgb_free(resp); + exit(-1); + } } trx = ts->trx; -- To view, visit https://gerrit.osmocom.org/907 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3fccc8e45843d255b256a753547436c39bbf38b0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 22 15:41:02 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 22 Sep 2016 15:41:02 +0000 Subject: [PATCH] libosmo-abis[master]: Remove use of private oRTP function Message-ID: Review at https://gerrit.osmocom.org/908 Remove use of private oRTP function ortp: the rtp_session_rtcp_recv() function is not part of public oRTP API so we shouldn't use it. Besides it is called internally by oRTP in rtp_session_recvm_with_ts() which we call anyway. Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 --- M src/trau/osmo_ortp.c 1 file changed, 2 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/08/908/1 diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index cc1d748..1ada83d 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -205,12 +205,10 @@ static int osmo_rtcp_fd_cb(struct osmo_fd *fd, unsigned int what) { - struct osmo_rtp_socket *rs = fd->data; - - /* We probably don't need this at all, as + /* Nothing to see here, move along: * rtp_session_recvm_with_ts() will alway also poll the RTCP * file descriptor for new data */ - return rtp_session_rtcp_recv(rs->sess); + return 0; } static int osmo_rtp_socket_fdreg(struct osmo_rtp_socket *rs) -- To view, visit https://gerrit.osmocom.org/908 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Thu Sep 22 15:50:32 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 22 Sep 2016 15:50:32 +0000 Subject: [PATCH] osmo-bts[master]: DTX: fix SID repeat scheduling In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/857 to look at the new patch set (#3). DTX: fix SID repeat scheduling Previously SID retransmission was scheduled incorrectly based on GSM frames instead of voice frames. Fix this by using GSM Fn only as elapsed time estimation: * move saved SID retransmission into generic function from lc15 and sysmo specific code * split retransmission time check into separate generic function * compute estimation for elapsed time since last retransmission using GSM Fn Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Fixes: OS#1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 66 insertions(+), 116 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/57/857/3 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..cde7a93 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -23,6 +23,8 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, uint32_t fn, bool update); +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..967b10d 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -111,6 +112,49 @@ memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type) or 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + return 0; +} + +/*! \brief Check if enough time has passed since last SID (if any) to repeat it + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +{ + /* Compute approx. time delta based on Fn duration */ + uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.last_sid.fn); + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 8) + return true; + return false; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 3) + return true; + return false; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5badc4d..4fdf6a6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -463,27 +463,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -506,30 +485,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -541,14 +503,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -556,14 +513,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 6c78ceb..ee72e53 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -566,27 +566,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -609,30 +588,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -644,14 +606,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -659,14 +616,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/857 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:49:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:49:10 +0000 Subject: osmo-iuh[master]: ranap: include port in RTP TransportLayerInformation In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/849 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I45fb134959dea9bcdfbfd9d8a061e67c3cc80fb7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:51:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:51:01 +0000 Subject: [MERGED] osmo-iuh[master]: ranap: include port in RTP TransportLayerInformation In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: ranap: include port in RTP TransportLayerInformation ...................................................................... ranap: include port in RTP TransportLayerInformation Remove an #if 0 to properly include the port information (verified to work). Adjust test expectations. Change-Id: I45fb134959dea9bcdfbfd9d8a061e67c3cc80fb7 --- M src/ranap_msg_factory.c M src/tests/test-ranap.ok 2 files changed, 4 insertions(+), 9 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 695a6be..94eb1c5 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -653,14 +653,9 @@ RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); uint8_t binding_id[4]; -#if 0 binding_id[0] = port >> 8; binding_id[1] = port & 0xff; binding_id[2] = binding_id[3] = 0; -#else - binding_id[0] = binding_id[1] = binding_id[2] = 0; - binding_id[3] = 1; -#endif new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; diff --git a/src/tests/test-ranap.ok b/src/tests/test-ranap.ok index 841edad..2ad19e6 100644 --- a/src/tests/test-ranap.ok +++ b/src/tests/test-ranap.ok @@ -91,7 +91,7 @@ 38 02 D8 01 2F A7 20 2F A8 00 00 F4 4C 08 0A 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3C 40 00 00 00 50 3D 02 00 02 0D C0 35 00 - 01 0A 0B 0C 0D 40 00 00 00 01 + 01 0A 0B 0C 0D 40 09 26 00 00 00 @@ -103,11 +103,11 @@ 00 00 01 00 35 00 3A 38 02 D8 01 2F A7 20 2F A8 00 00 F4 4C 08 0A 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3C 40 00 00 00 50 3D - 02 00 02 0D C0 35 00 01 0A 0B 0C 0D 40 00 00 00 - 01 40 01 00 + 02 00 02 0D C0 35 00 01 0A 0B 0C 0D 40 09 26 00 + 00 40 01 00 -00 00 00 4b 00 00 01 00 36 40 44 00 00 01 00 35 00 3a 38 02 d8 01 2f a7 20 2f a8 00 00 f4 4c 08 0a 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3c 40 00 00 00 50 3d 02 00 02 0d c0 35 00 01 0a 0b 0c 0d 40 00 00 00 01 40 01 00 +00 00 00 4b 00 00 01 00 36 40 44 00 00 01 00 35 00 3a 38 02 d8 01 2f a7 20 2f a8 00 00 f4 4c 08 0a 02 80 00 51 40 00 27 20 28 14 00 67 40 00 00 22 28 14 00 3c 40 00 00 00 50 3d 02 00 02 0d c0 35 00 01 0a 0b 0c 0d 40 09 26 00 00 40 01 00 ==> RAB ASSIGNMENT COMMAND (DATA) -- To view, visit https://gerrit.osmocom.org/849 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I45fb134959dea9bcdfbfd9d8a061e67c3cc80fb7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:56:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:56:58 +0000 Subject: [PATCH] osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification Message-ID: Review at https://gerrit.osmocom.org/909 hnbgw: UE context: add handling by tmsi identification To prepare for an upcoming commit that accepts TMSI identification upon UE Register Requests: Add tmsi arg to ue_context_alloc(). Add ue_context_by_tmsi(). Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_hnbap.c 3 files changed, 23 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/09/909/1 diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index 21a9602..bee7fb6 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -101,8 +101,7 @@ /*! Unique Context ID for this UE */ uint32_t context_id; char imsi[16+1]; - /* TODO: track TMSI, for HNBAP UE Register Request with TMSI, - * seen with ip.access nano3G femto cell */ + uint32_t tmsi; /*! UE is serviced via this HNB */ struct hnb_context *hnb; }; @@ -139,7 +138,9 @@ struct ue_context *ue_context_by_id(struct hnb_gw *gw, uint32_t id); struct ue_context *ue_context_by_imsi(struct hnb_gw *gw, const char *imsi); -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi); +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi); +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi); void ue_context_free(struct ue_context *ue); struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd); diff --git a/src/hnbgw.c b/src/hnbgw.c index d50e622..0e711db 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -111,6 +111,17 @@ return NULL; } +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi) +{ + struct ue_context *ue; + + llist_for_each_entry(ue, &gw->ue_list, list) { + if (ue->tmsi == tmsi) + return ue; + } + return NULL; +} + void ue_context_free_by_hnb(struct hnb_gw *gw, const struct hnb_context *hnb) { struct ue_context *ue, *tmp; @@ -132,7 +143,8 @@ return id; } -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi) +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi) { struct ue_context *ue; @@ -141,7 +153,11 @@ return NULL; ue->hnb = hnb; - strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + if (imsi) + strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + else + ue->imsi[0] = '\0'; + ue->tmsi = tmsi; ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 7bf54c8..dab6f4f 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -260,7 +260,7 @@ ue = ue_context_by_imsi(ctx->gw, imsi); if (!ue) - ue = ue_context_alloc(ctx, imsi); + ue = ue_context_alloc(ctx, imsi, 0); hnbap_free_ueregisterrequesties(&ies); /* Send UERegisterAccept */ -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:56:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:56:58 +0000 Subject: [PATCH] osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI Message-ID: Review at https://gerrit.osmocom.org/910 hnbap: accept UE Register Requests with TMSI and pTMSI HNBGW so far keeps track of UEs that have registered, with their IMSI. When a UE registers with only a TMSI, we obviously can't store an IMSI. However, since we're so far never *using* the list of UEs in osmo-hnbgw, we might as well just accept the TMSI registration and carry on as usual. All that is needed for proper operation is a valid UE context. This is particularly helpful with an ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. So far this caused failures and the need to make the UE clear its TMSI (wait several minutes or attempt to subscribe to a different network), so that UE registration switched back to IMSI. When simply accepting the TMSI in osmo-hngw, no problems are apparent in our current code state. For example, a Samsung Galaxy S4 seems to send a UE_Identity_PR_tMSILAI (CS identity), and a GT-I9100 seems to send a UE_Identity_PR_pTMSIRAI (PS identity) upon first registration to the network. Recording the IMSI in hnbgw: we could use the subscriber list during paging, but on the other hand, it doesn't hurt to anyway always page to all HNBs connected to osmo-hnbgw. The paging procedure does include a page-to-all-HNBs in case the first HNB paging fails. However, since we're now failing to record UEs that register by TMSI, we must be aware that trying to page such UE on only its last seen HNB will fail; it is plainly missing in the list. Patch-by: Harald Welte , me Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 --- M src/hnbgw_hnbap.c 1 file changed, 83 insertions(+), 44 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/10/910/1 diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index dab6f4f..2f3a717 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -114,65 +114,100 @@ return hnbgw_hnbap_tx(ue->hnb, msg); } -static int hnbgw_tx_ue_register_rej_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id) +static int hnbgw_tx_ue_register_acc_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id) { - UERegisterReject_t reject_out; - UERegisterRejectIEs_t reject; + UERegisterAccept_t accept_out; + UERegisterAcceptIEs_t accept; struct msgb *msg; + uint32_t ctx_id; + uint32_t tmsi = 0; + struct ue_context *ue; int rc; - memset(&reject, 0, sizeof(reject)); - reject.uE_Identity.present = ue_id->present; + memset(&accept, 0, sizeof(accept)); + accept.uE_Identity.present = ue_id->present; - if (ue_id->present != UE_Identity_PR_tMSILAI) { - LOGP(DHNBAP, LOGL_ERROR, "Trying to reject UE Register without IMSI: only rejects of UE_Identity_PR_tMSILAI supported so far.\n"); + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.tMSILAI.tMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + break; + case UE_Identity_PR_pTMSIRAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.pTMSI, + ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size * 8 + - ue_id->choice.pTMSIRAI.pTMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.pTMSIRAI.pTMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.rAC, + ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size); + break; + default: + LOGP(DHNBAP, LOGL_ERROR, "Unsupportedccept UE ID (present=%d)\n", + ue_id->present); return -1; } - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", - ue_id->choice.tMSILAI.tMSI.size, - osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size)); + tmsi = ntohl(tmsi); + LOGP(DHNBAP, LOGL_DEBUG, "HNBAP register with TMSI %x\n", + tmsi); - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", - ue_id->choice.tMSILAI.lAI.pLMNID.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size)); + ue = ue_context_by_tmsi(hnb->gw, tmsi); + if (!ue) + ue = ue_context_alloc(hnb, NULL, tmsi); - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", - ue_id->choice.tMSILAI.lAI.lAC.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size)); + asn1_u24_to_bitstring(&accept.context_ID, &ctx_id, ue->context_id); - BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, - ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size * 8 - - ue_id->choice.tMSILAI.tMSI.bits_unused); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, - ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, - ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size); - - reject.cause.present = Cause_PR_radioNetwork; - reject.cause.choice.radioNetwork = CauseRadioNetwork_invalid_UE_identity; - - memset(&reject_out, 0, sizeof(reject_out)); - rc = hnbap_encode_ueregisterrejecties(&reject_out, &reject); + memset(&accept_out, 0, sizeof(accept_out)); + rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept); if (rc < 0) { return rc; } - msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister, - Criticality_reject, - &asn_DEF_UERegisterReject, - &reject_out); + msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister, + Criticality_reject, + &asn_DEF_UERegisterAccept, + &accept_out); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, &reject.uE_Identity.choice.tMSILAI.tMSI); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.lAC); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out); + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.lAC); + break; + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + default: + break; + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterAccept, &accept_out); return hnbgw_hnbap_tx(hnb, msg); } @@ -246,11 +281,15 @@ ranap_bcd_decode(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf, ies.uE_Identity.choice.iMSIESN.iMSIDS41.size); break; + case UE_Identity_PR_tMSILAI: + case UE_Identity_PR_pTMSIRAI: + rc = hnbgw_tx_ue_register_acc_tmsi(ctx, &ies.uE_Identity); + hnbap_free_ueregisterrequesties(&ies); + return rc; default: LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n"); /* TODO: this is probably a TMSI registration. Store TMSIs * and look them up to accept UE Registration. */ - rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); hnbap_free_ueregisterrequesties(&ies); return rc; } -- To view, visit https://gerrit.osmocom.org/910 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:57:44 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:57:44 +0000 Subject: [PATCH] osmo-iuh[master]: log hnbap UE context allocation Message-ID: Review at https://gerrit.osmocom.org/911 log hnbap UE context allocation Change-Id: I572095e6d3f2b48362bf8a88bc66f8438348d29a --- M src/hnbgw.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/11/911/1 diff --git a/src/hnbgw.c b/src/hnbgw.c index d50e622..0bded80 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -145,6 +145,9 @@ ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); + LOGP(DHNBAP, LOGL_INFO, "created UE context: imsi %s tmsi 0x%x\n", + imsi? imsi : "-", tmsi); + return ue; } -- To view, visit https://gerrit.osmocom.org/911 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I572095e6d3f2b48362bf8a88bc66f8438348d29a Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 17:57:44 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 17:57:44 +0000 Subject: [PATCH] osmo-iuh[master]: comment: note RAB assignment spec reference Message-ID: Review at https://gerrit.osmocom.org/912 comment: note RAB assignment spec reference Change-Id: Ifef8da82a01cd781ef560d1ec21cbfb23efb1495 --- M src/ranap_msg_factory.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/12/912/1 diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 94eb1c5..16a9d03 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -705,7 +705,10 @@ id->bits_unused = 0; } -/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ +/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice). + * See 3GPP TS 25.413 8.2. + * RAB ID: 3GPP TS 25.413 9.2.1.2 + */ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port, bool use_x213_nsap) -- To view, visit https://gerrit.osmocom.org/912 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifef8da82a01cd781ef560d1ec21cbfb23efb1495 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:22:47 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 18:22:47 +0000 Subject: libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has restored this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:44:38 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 18:44:38 +0000 Subject: [ABANDON] libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:50:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:50:47 +0000 Subject: [PATCH] openbsc[master]: cosmetic fixes in libcommon/talloc_ctx.c Message-ID: Review at https://gerrit.osmocom.org/919 cosmetic fixes in libcommon/talloc_ctx.c Add copyright notice, remove obsolete include, remove unneeded line break. Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 --- M openbsc/src/libcommon/talloc_ctx.c 1 file changed, 19 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/19/919/1 diff --git a/openbsc/src/libcommon/talloc_ctx.c b/openbsc/src/libcommon/talloc_ctx.c index ae6a156..4a81bf7 100644 --- a/openbsc/src/libcommon/talloc_ctx.c +++ b/openbsc/src/libcommon/talloc_ctx.c @@ -1,5 +1,23 @@ +/* OpenBSC allocation contexts initialization code */ +/* (C) 2011-2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * 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 . + * + */ + #include -#include extern void *tall_msgb_ctx; extern void *tall_fle_ctx; -- To view, visit https://gerrit.osmocom.org/919 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: bsc_init: don't pass telnet dummy conn Message-ID: Review at https://gerrit.osmocom.org/920 mscsplit: bsc_init: don't pass telnet dummy conn We want to create the telnet for VTY only after reading the config file, and the dummy_conn was a workaround to be able to do so, but is not needed: gsmnet_from_vty() used to expect vty->priv to point to a gsm_network struct, but that is not actually the case anymore. It is using a static pointer to store the gsm_network struct instead. Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 --- M openbsc/src/libbsc/bsc_init.c 1 file changed, 1 insertion(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/20/920/1 diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 989fca8..371ddee 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -473,7 +473,6 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *), const char *config_file) { - struct telnet_connection dummy_conn; struct gsm_bts *bts; int rc; @@ -485,9 +484,7 @@ bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC"); bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC"); - /* our vty command code expects vty->priv to point to a telnet_connection */ - dummy_conn.priv = bsc_gsmnet; - rc = vty_read_config_file(config_file, &dummy_conn); + rc = vty_read_config_file(config_file, NULL); if (rc < 0) { LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file); return rc; -- To view, visit https://gerrit.osmocom.org/920 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: move subscriber conns list into struct gsm_network Message-ID: Review at https://gerrit.osmocom.org/921 mscsplit: 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(), callers now access gsm_network->subscr_conns directly. This allows using the subscr_conns from libmsc without having to link libbsc. Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c --- M openbsc/include/openbsc/bsc_api.h M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c M openbsc/src/libbsc/net_init.c M openbsc/src/osmo-bsc/osmo_bsc_ctrl.c 5 files changed, 8 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/21/921/1 diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h index a3d12f2..3a93119 100644 --- a/openbsc/include/openbsc/bsc_api.h +++ b/openbsc/include/openbsc/bsc_api.h @@ -52,6 +52,4 @@ 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 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 9317717..07db02f 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -345,6 +345,9 @@ /* Allow or disallow TCH/F on dynamic TCH/F_TCH/H_PDCH; OS#1778 */ bool dyn_ts_allow_tch_f; /* TODO: vty for this; related: OS#1781 */ + + /* all active subscriber connections. */ + struct llist_head subscr_conns; }; struct osmo_esme; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 8c830a3..f42598a 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -39,7 +39,6 @@ #define GSM0808_T10_VALUE 6, 0 -static LLIST_HEAD(sub_connections); static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind); static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id); @@ -242,15 +241,16 @@ struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan) { struct gsm_subscriber_connection *conn; + struct gsm_network *net = lchan->ts->trx->bts->network; - conn = talloc_zero(lchan->ts->trx->bts->network, struct gsm_subscriber_connection); + conn = talloc_zero(net, struct gsm_subscriber_connection); if (!conn) return NULL; conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; - llist_add_tail(&conn->entry, &sub_connections); + llist_add_tail(&conn->entry, &net->subscr_conns); return conn; } @@ -876,7 +876,3 @@ osmo_signal_register_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL); } -struct llist_head *bsc_api_sub_connections(struct gsm_network *net) -{ - return &sub_connections; -} diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 65419ae..e01ba80 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -79,6 +79,7 @@ INIT_LLIST_HEAD(&net->trans_list); INIT_LLIST_HEAD(&net->upqueue); INIT_LLIST_HEAD(&net->bts_list); + INIT_LLIST_HEAD(&net->subscr_conns); /* init statistics */ net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c index 72f80ed..3010b55 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c @@ -583,7 +583,7 @@ alert = atoi(alert_str); net = cmd->node; - llist_for_each_entry(conn, bsc_api_sub_connections(net), entry) { + llist_for_each_entry(conn, &net->subscr_conns, entry) { if (!conn->sccp_con) continue; -- To view, visit https://gerrit.osmocom.org/921 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: gsm_network_init(): add explicit root talloc ctx Message-ID: Review at https://gerrit.osmocom.org/922 mscsplit: gsm_network_init(): add explicit root talloc ctx Decouple the root talloc context from libbsc's global talloc_bsc_ctx. This allows to define the root talloc ctx from a main() scope, which in turn helps decouple libmsc from libbsc. Change-Id: I92f6b47b1eeea2e8f3fba66f25d7e708e5659f8a --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/bsc_init.c M openbsc/src/libbsc/net_init.c M openbsc/src/utils/bs11_config.c M openbsc/tests/channel/channel_test.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 14 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/22/922/1 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 07db02f..fbb0356 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -394,8 +394,11 @@ char text[SMS_TEXT_SIZE]; }; -struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code, +struct gsm_network *gsm_network_init(void *ctx, + 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); /* Get reference to a neighbor cell on a given BCCH ARFCN */ diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 31da056..9e3a471 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -983,7 +983,7 @@ } libosmo_abis_init(tall_ctx_config); - bsc_gsmnet = gsm_network_init(1, 1, NULL); + bsc_gsmnet = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); if (!bsc_gsmnet) exit(1); diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 371ddee..06f4121 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -477,7 +477,7 @@ int rc; /* initialize our data structures */ - bsc_gsmnet = gsm_network_init(1, 1, mncc_recv); + bsc_gsmnet = gsm_network_init(tall_bsc_ctx, 1, 1, mncc_recv); if (!bsc_gsmnet) return -ENOMEM; diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index e01ba80..e53b466 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -23,13 +23,15 @@ #include -struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code, +struct gsm_network *gsm_network_init(void *ctx, + uint16_t country_code, + uint16_t network_code, int (*mncc_recv)(struct gsm_network *, struct msgb *)) { struct gsm_network *net; const char *default_regexp = ".*"; - net = talloc_zero(tall_bsc_ctx, struct gsm_network); + net = talloc_zero(ctx, struct gsm_network); if (!net) return NULL; diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c index 3fb74bf..227b9f8 100644 --- a/openbsc/src/utils/bs11_config.c +++ b/openbsc/src/utils/bs11_config.c @@ -894,7 +894,7 @@ handle_options(argc, argv); bts_model_bs11_init(); - gsmnet = gsm_network_init(1, 1, NULL); + gsmnet = gsm_network_init(tall_bs11cfg_ctx, 1, 1, NULL); if (!gsmnet) { fprintf(stderr, "Unable to allocate gsm network\n"); exit(1); diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 5674607..924d763 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -68,7 +68,7 @@ printf("Testing the gsm_subscriber chan logic\n"); /* Create a dummy network */ - network = gsm_network_init(1, 1, NULL); + network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); if (!network) exit(1); bts = gsm_bts_alloc(network); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 7acc93f..e81394f 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -122,7 +122,7 @@ static inline void test_si2q_u(void) { struct gsm_bts *bts; - struct gsm_network *network = gsm_network_init(1, 1, NULL); + struct gsm_network *network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater UARFCN generation:\n"); if (!network) @@ -149,7 +149,7 @@ static inline void test_si2q_e(void) { struct gsm_bts *bts; - struct gsm_network *network = gsm_network_init(1, 1, NULL); + struct gsm_network *network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater EARFCN generation:\n"); if (!network) -- To view, visit https://gerrit.osmocom.org/922 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I92f6b47b1eeea2e8f3fba66f25d7e708e5659f8a Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx Message-ID: Review at https://gerrit.osmocom.org/923 mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx Decouple the talloc context allocations from global tall_bsc_ctx pointer. It appears that talloc_ctx_init() was intended for general use, since it is located in libcommon. It is currently used only by osmo-nitb; but the upcoming osmo-cscn will use it as well. Instead of defining in osmo-nitb main file, add definition in gsm_data.h. Change-Id: I168106599b788f586be0ff0af4699b9746c1b103 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libcommon/talloc_ctx.c M openbsc/src/osmo-nitb/bsc_hack.c 3 files changed, 19 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/23/923/1 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index fbb0356..26efeaa 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -394,6 +394,8 @@ char text[SMS_TEXT_SIZE]; }; +extern void talloc_ctx_init(void *ctx_root); + struct gsm_network *gsm_network_init(void *ctx, uint16_t country_code, uint16_t network_code, diff --git a/openbsc/src/libcommon/talloc_ctx.c b/openbsc/src/libcommon/talloc_ctx.c index ae6a156..f039650 100644 --- a/openbsc/src/libcommon/talloc_ctx.c +++ b/openbsc/src/libcommon/talloc_ctx.c @@ -17,22 +17,21 @@ extern void *tall_upq_ctx; extern void *tall_ctr_ctx; -void talloc_ctx_init(void) +void talloc_ctx_init(void *ctx_root) { - tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb"); - tall_fle_ctx = talloc_named_const(tall_bsc_ctx, 0, - "bs11_file_list_entry"); - tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 0, "loc_updating_oper"); - tall_authciphop_ctx = talloc_named_const(tall_bsc_ctx, 0, "auth_ciph_oper"); - tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 0, "sms"); - tall_subscr_ctx = talloc_named_const(tall_bsc_ctx, 0, "subscriber"); - tall_sub_req_ctx = talloc_named_const(tall_bsc_ctx, 0, "subscr_request"); - tall_call_ctx = talloc_named_const(tall_bsc_ctx, 0, "gsm_call"); - tall_paging_ctx = talloc_named_const(tall_bsc_ctx, 0, "paging_request"); - tall_sigh_ctx = talloc_named_const(tall_bsc_ctx, 0, "signal_handler"); - tall_tqe_ctx = talloc_named_const(tall_bsc_ctx, 0, "subch_txq_entry"); - tall_trans_ctx = talloc_named_const(tall_bsc_ctx, 0, "transaction"); - tall_map_ctx = talloc_named_const(tall_bsc_ctx, 0, "trau_map_entry"); - tall_upq_ctx = talloc_named_const(tall_bsc_ctx, 0, "trau_upq_entry"); - tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter"); + tall_msgb_ctx = talloc_named_const(ctx_root, 0, "msgb"); + tall_fle_ctx = talloc_named_const(ctx_root, 0, "bs11_file_list_entry"); + tall_locop_ctx = talloc_named_const(ctx_root, 0, "loc_updating_oper"); + tall_authciphop_ctx = talloc_named_const(ctx_root, 0, "auth_ciph_oper"); + tall_gsms_ctx = talloc_named_const(ctx_root, 0, "sms"); + tall_subscr_ctx = talloc_named_const(ctx_root, 0, "subscriber"); + tall_sub_req_ctx = talloc_named_const(ctx_root, 0, "subscr_request"); + tall_call_ctx = talloc_named_const(ctx_root, 0, "gsm_call"); + tall_paging_ctx = talloc_named_const(ctx_root, 0, "paging_request"); + tall_sigh_ctx = talloc_named_const(ctx_root, 0, "signal_handler"); + tall_tqe_ctx = talloc_named_const(ctx_root, 0, "subch_txq_entry"); + tall_trans_ctx = talloc_named_const(ctx_root, 0, "transaction"); + tall_map_ctx = talloc_named_const(ctx_root, 0, "trau_map_entry"); + tall_upq_ctx = talloc_named_const(ctx_root, 0, "trau_upq_entry"); + tall_ctr_ctx = talloc_named_const(ctx_root, 0, "counter"); } diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 976aefa..67efe4f 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -243,8 +243,6 @@ osmo_timer_schedule(&bsc_gsmnet->subscr_expire_timer, EXPIRE_INTERVAL); } -void talloc_ctx_init(void); - extern int bsc_vty_go_parent(struct vty *vty); static struct vty_app_info vty_info = { @@ -261,7 +259,7 @@ vty_info.copyright = openbsc_copyright; tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc"); - talloc_ctx_init(); + talloc_ctx_init(tall_bsc_ctx); on_dso_load_token(); on_dso_load_rrlp(); on_dso_load_ho_dec(); -- To view, visit https://gerrit.osmocom.org/923 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I168106599b788f586be0ff0af4699b9746c1b103 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet Message-ID: Review at https://gerrit.osmocom.org/924 mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet Add an explicit gsm_network pointer instead of using the bsc_gsmnet global. This allows passing a gsm_network struct from the main() scope, which helps to decouple libmsc from libbsc. Change-Id: I9e2c0d9c18d4cebb5efb71565ad84df2bc2e0251 --- M openbsc/include/openbsc/vty.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/osmo-bsc/osmo_bsc_main.c M openbsc/src/osmo-bsc_nat/bsc_nat_vty.c M openbsc/src/osmo-nitb/bsc_hack.c 5 files changed, 5 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/24/924/1 diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index bc30e23..78e87f0 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -43,7 +43,7 @@ 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); #endif diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 5c95e85..cb0b1d8 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -4028,7 +4028,7 @@ extern int bsc_vty_init_extra(void); -int bsc_vty_init(const struct log_info *cat) +int bsc_vty_init(const struct log_info *cat, struct gsm_network *network) { cfg_ts_pchan_cmd.string = vty_cmd_string_from_valstr(tall_bsc_ctx, diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 3594a5b..2ee5fb4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -204,7 +204,7 @@ /* This needs to precede handle_options() */ vty_info.copyright = openbsc_copyright; vty_init(&vty_info); - bsc_vty_init(&log_info); + bsc_vty_init(&log_info, bsc_gsmnet); bsc_msg_lst_vty_init(tall_bsc_ctx, &access_lists, BSC_NODE); ctrl_vty_init(tall_bsc_ctx); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c index 3708bc2..706e507 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c @@ -1329,7 +1329,7 @@ /* called by the telnet interface... we have our own init above */ -int bsc_vty_init(const struct log_info *cat) +int bsc_vty_init(const struct log_info *cat, struct gsm_network *network) { logging_vty_add_cmds(cat); return 0; diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 67efe4f..8e1ddae 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -271,7 +271,7 @@ /* This needs to precede handle_options() */ vty_init(&vty_info); - bsc_vty_init(&log_info); + bsc_vty_init(&log_info, bsc_gsmnet); ctrl_vty_init(tall_bsc_ctx); #ifdef BUILD_SMPP -- To view, visit https://gerrit.osmocom.org/924 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9e2c0d9c18d4cebb5efb71565ad84df2bc2e0251 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: abis vty: decouple from global bsc_gsmnet variable Message-ID: Review at https://gerrit.osmocom.org/925 mscsplit: abis vty: decouple from global bsc_gsmnet variable Publish gsmnet_from_vty() in openbsc/vty.h and use in the abis VTY functions. Change-Id: Ib65a18db06b8bc4fc7d56bf56dd64a52cc1cd253 --- M openbsc/include/openbsc/vty.h M openbsc/src/libbsc/abis_nm_vty.c M openbsc/src/libbsc/abis_om2000_vty.c 3 files changed, 6 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/25/925/1 diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index 78e87f0..315db0d 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -46,4 +46,6 @@ int bsc_vty_init(const struct log_info *cat, struct gsm_network *network); int bsc_vty_init_extra(void); +struct gsm_network *gsmnet_from_vty(struct vty *vty); + #endif diff --git a/openbsc/src/libbsc/abis_nm_vty.c b/openbsc/src/libbsc/abis_nm_vty.c index a14e5c2..6ec0a4a 100644 --- a/openbsc/src/libbsc/abis_nm_vty.c +++ b/openbsc/src/libbsc/abis_nm_vty.c @@ -94,7 +94,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -128,7 +128,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; diff --git a/openbsc/src/libbsc/abis_om2000_vty.c b/openbsc/src/libbsc/abis_om2000_vty.c index 8325e29..72422a1 100644 --- a/openbsc/src/libbsc/abis_om2000_vty.c +++ b/openbsc/src/libbsc/abis_om2000_vty.c @@ -82,7 +82,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -122,7 +122,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; -- To view, visit https://gerrit.osmocom.org/925 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib65a18db06b8bc4fc7d56bf56dd64a52cc1cd253 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: add gsm_network backpointer to gsm_subscriber_conn... Message-ID: Review at https://gerrit.osmocom.org/926 mscsplit: add gsm_network backpointer to gsm_subscriber_connection We want to be able to use a network backpointer without having to go through a gsm_bts struct. This commit adds the network pointer, the subsequent commit applies direct access to the network structure from gsm_subscriber_connection. Change-Id: If8870972f1b3e333c2a4cce97cdc95bdee0382a1 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c 2 files changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/26/926/1 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 26efeaa..ffb7dd2 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -134,6 +134,8 @@ struct osmo_bsc_sccp_con *sccp_con; /* back pointers */ + struct gsm_network *network; + int in_release; struct gsm_lchan *lchan; struct gsm_lchan *ho_lchan; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index f42598a..02751f4 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -247,6 +247,7 @@ if (!conn) return NULL; + conn->network = net; conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; -- To view, visit https://gerrit.osmocom.org/926 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If8870972f1b3e333c2a4cce97cdc95bdee0382a1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:56:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 18:56:17 +0000 Subject: [PATCH] openbsc[master]: mscsplit: directly access gsm_network backpointer from gsm_s... Message-ID: Review at https://gerrit.osmocom.org/927 mscsplit: directly access gsm_network backpointer from gsm_subscriber_connection The previous commit added a network backpointer to gsm_subscriber_connection. Use it wherever it makes sense, to skip the step through the bts structure. In some places, remove local variables that become unused. Change-Id: I34537025986713291e14c8212a81539b497befd4 --- M openbsc/src/libbsc/bsc_api.c M openbsc/src/libmsc/gsm_04_08.c M openbsc/src/libmsc/gsm_04_11.c M openbsc/src/libmsc/rrlp.c M openbsc/src/libmsc/transaction.c 5 files changed, 53 insertions(+), 60 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/27/927/1 diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 02751f4..cc12e9f 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -146,7 +146,7 @@ conn->secondary_lchan = NULL; /* inform them about the failure */ - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL); } @@ -157,7 +157,7 @@ struct gsm_lchan *lchan, int full_rate) { struct bsc_api *api; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; struct amr_multirate_conf *mr; struct gsm48_multi_rate_conf *mr_conf; @@ -387,7 +387,7 @@ int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate) { struct bsc_api *api; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; if (!chan_compat_with_mode(conn->lchan, chan_mode, full_rate)) { if (handle_new_assignment(conn, chan_mode, full_rate) != 0) @@ -424,7 +424,7 @@ struct msgb *msg) { struct gsm48_hdr *gh; - struct bsc_api *api = conn->bts->network->bsc_api; + struct bsc_api *api = conn->network->bsc_api; if (conn->secondary_lchan != msg->lchan) { LOGP(DMSC, LOGL_ERROR, "Assignment Compl should occur on second lchan.\n"); @@ -461,7 +461,7 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct bsc_api *api = conn->bts->network->bsc_api; + struct bsc_api *api = conn->network->bsc_api; uint8_t *rr_failure; struct gsm48_hdr *gh; @@ -751,7 +751,7 @@ if (!conn) return; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; if (!api || !api->sapi_n_reject) return; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 08dac63..aa3d78a9 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -187,7 +187,7 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, gsm_cbfn *cb, void *cb_data) { - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_subscriber *subscr = conn->subscr; struct gsm_security_operation *op; struct gsm_auth_tuple atuple; @@ -321,7 +321,7 @@ static int finish_lu(struct gsm_subscriber_connection *conn) { int rc = 0; - int avoid_tmsi = conn->bts->network->avoid_tmsi; + int avoid_tmsi = conn->network->avoid_tmsi; /* We're all good */ if (avoid_tmsi) { @@ -332,7 +332,7 @@ } rc = gsm0408_loc_upd_acc(conn); - if (conn->bts->network->send_mm_info) { + if (conn->network->send_mm_info) { /* send MM INFO with network name */ rc = gsm48_tx_mm_info(conn); } @@ -429,7 +429,7 @@ * we have a subscriber connection. */ restart: - llist_for_each_entry_safe(trans, temp, &conn->bts->network->trans_list, entry) { + llist_for_each_entry_safe(trans, temp, &conn->network->trans_list, entry) { if (trans->conn == conn) { trans_free(trans); goto restart; @@ -457,7 +457,7 @@ struct gsm_bts *bts = conn->bts; struct msgb *msg; - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_REJECT]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_REJECT]); msg = gsm48_create_loc_upd_rej(cause); if (!msg) { @@ -477,7 +477,6 @@ /* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn) { - struct gsm_bts *bts = conn->bts; struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC"); struct gsm48_hdr *gh; struct gsm48_loc_area_id *lai; @@ -490,8 +489,9 @@ gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT; lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); - gsm48_generate_lai(lai, bts->network->country_code, - bts->network->network_code, bts->location_area_code); + gsm48_generate_lai(lai, conn->network->country_code, + conn->network->network_code, + conn->bts->location_area_code); if (conn->subscr->tmsi == GSM_RESERVED_TMSI) { uint8_t mi[10]; @@ -506,7 +506,7 @@ DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n"); - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_ACCEPT]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_ACCEPT]); return gsm48_conn_sendmsg(msg, conn, NULL); } @@ -543,9 +543,7 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm_lchan *lchan = msg->lchan; - struct gsm_bts *bts = lchan->ts->trx->bts; - struct gsm_network *net = bts->network; + struct gsm_network *net = conn->network; uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; char mi_string[GSM48_MI_SIZE]; @@ -565,7 +563,7 @@ conn->subscr = subscr_create(net, mi_string); } if (!conn->subscr && conn->loc_operation) { - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, net->reject_cause); release_loc_updating_req(conn, 1); return 0; } @@ -592,11 +590,9 @@ static void loc_upd_rej_cb(void *data) { struct gsm_subscriber_connection *conn = data; - struct gsm_lchan *lchan = conn->lchan; - struct gsm_bts *bts = lchan->ts->trx->bts; LOGP(DMM, LOGL_DEBUG, "Location Updating Request procedure timedout.\n"); - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, conn->network->reject_cause); release_loc_updating_req(conn, 1); } @@ -620,7 +616,6 @@ struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_loc_upd_req *lu; struct gsm_subscriber *subscr = NULL; - struct gsm_bts *bts = conn->bts; uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; @@ -637,13 +632,13 @@ switch (lu->type) { case GSM48_LUPD_NORMAL: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); break; case GSM48_LUPD_IMSI_ATT: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); break; case GSM48_LUPD_PERIODIC: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); break; } @@ -670,12 +665,11 @@ conn->loc_operation->waiting_for_imei = 1; /* look up subscriber based on IMSI, create if not found */ - subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string); + subscr = subscr_get_by_imsi(conn->network->subscr_group, mi_string); if (!subscr) - subscr = subscr_create(bts->network, mi_string); - + subscr = subscr_create(conn->network, mi_string); if (!subscr) { - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, conn->network->reject_cause); release_loc_updating_req(conn, 0); return 0; } @@ -683,7 +677,7 @@ case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); /* look up the subscriber based on TMSI, request IMSI if it fails */ - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(conn->network->subscr_group, tmsi_from_string(mi_string)); if (!subscr) { /* send IDENTITY REQUEST message to get IMSI */ @@ -738,7 +732,7 @@ { struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF"); struct gsm48_hdr *gh; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_bts *bts = conn->bts; uint8_t *ptr8; int name_len, name_pad; @@ -973,7 +967,7 @@ uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; - struct gsm_bts *bts = conn->bts; + struct gsm_network *network = conn->network; struct gsm_subscriber *subscr; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_service_request *req = @@ -1004,13 +998,13 @@ DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", req->cm_service_type, gsm48_mi_type_name(mi_type), mi_string); - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(network->subscr_group, mi_string); } else if (mi_type == GSM_MI_TYPE_TMSI) { DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", req->cm_service_type, gsm48_mi_type_name(mi_type), mi_string); - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(network->subscr_group, tmsi_from_string(mi_string)); } else { DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type); @@ -1020,7 +1014,7 @@ osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len)); - if (is_siemens_bts(bts)) + if (is_siemens_bts(conn->bts)) send_siemens_mrpci(msg->lchan, classmark2-1); @@ -1051,7 +1045,7 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct gsm_bts *bts = conn->bts; + struct gsm_network *network = conn->network; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_imsi_detach_ind *idi = (struct gsm48_imsi_detach_ind *) gh->data; @@ -1063,17 +1057,17 @@ DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s", gsm48_mi_type_name(mi_type), mi_string); - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); + rate_ctr_inc(&network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); switch (mi_type) { case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(network->subscr_group, tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: DEBUGPC(DMM, "\n"); - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(network->subscr_group, mi_string); break; case GSM_MI_TYPE_IMEI: @@ -1087,7 +1081,7 @@ } if (subscr) { - subscr_update(subscr, bts, + subscr_update(subscr, conn->bts, GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr)); @@ -1119,7 +1113,7 @@ { struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; DEBUGP(DMM, "MM AUTHENTICATION RESPONSE (sres = %s): ", osmo_hexdump(ar->sres, 4)); @@ -1200,7 +1194,6 @@ /* Receive a PAGING RESPONSE message from the MS */ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct gsm_bts *bts = conn->bts; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_pag_resp *resp; uint8_t *classmark2_lv = gh->data + 1; @@ -1217,11 +1210,11 @@ switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(conn->network->subscr_group, tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(conn->network->subscr_group, mi_string); break; } @@ -3595,7 +3588,7 @@ DEBUGP(DCC, "Unknown transaction ID %x, " "creating new trans.\n", transaction_id); /* Create transaction */ - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_CC, transaction_id, new_callref++); if (!trans) { diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 08d8fdf..3a2effe 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -309,20 +309,20 @@ #endif /* determine gsms->receiver based on dialled number */ - gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group, + gsms->receiver = subscr_get_by_extension(conn->network->subscr_group, gsms->dst.addr); if (!gsms->receiver) { #ifdef BUILD_SMPP /* Avoid a second look-up */ if (smpp_first) { - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); return 1; /* cause 1: unknown subscriber */ } rc = smpp_try_deliver(gsms, conn); if (rc == 1) { rc = 1; /* cause 1: unknown subscriber */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); } else if (rc < 0) { LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", subscr_name(conn->subscr), rc); @@ -333,7 +333,7 @@ } #else rc = 1; /* cause 1: unknown subscriber */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); #endif return rc; } @@ -374,7 +374,7 @@ uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */ int rc = 0; - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); gsms = sms_alloc(); if (!gsms) @@ -616,7 +616,7 @@ static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, struct gsm411_rp_hdr *rph) { - struct gsm_network *net = trans->conn->bts->network; + struct gsm_network *net = trans->conn->network; struct gsm_sms *sms = trans->sms.sms; uint8_t cause_len = rph->data[0]; uint8_t cause = rph->data[1]; @@ -816,7 +816,7 @@ if (!trans) { DEBUGP(DLSMS, " -> (new transaction)\n"); - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_SMS, transaction_id, new_callref++); if (!trans) { @@ -878,7 +878,7 @@ int rc; transaction_id = - trans_assign_trans_id(conn->bts->network, conn->subscr, + trans_assign_trans_id(conn->network, conn->subscr, GSM48_PDISC_SMS, 0); if (transaction_id == -1) { LOGP(DLSMS, LOGL_ERROR, "No available transaction ids\n"); @@ -891,7 +891,7 @@ DEBUGP(DLSMS, "%s()\n", __func__); /* FIXME: allocate transaction with message reference */ - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_SMS, transaction_id, new_callref++); if (!trans) { @@ -943,7 +943,7 @@ DEBUGP(DLSMS, "TX: SMS DELIVER\n"); - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); db_sms_inc_deliver_attempts(trans->sms.sms); return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, @@ -1037,7 +1037,7 @@ struct gsm_network *net; struct gsm_trans *trans, *tmp; - net = conn->bts->network; + net = conn->network; llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) { struct gsm_sms *sms; diff --git a/openbsc/src/libmsc/rrlp.c b/openbsc/src/libmsc/rrlp.c index 161456a..e695daa 100644 --- a/openbsc/src/libmsc/rrlp.c +++ b/openbsc/src/libmsc/rrlp.c @@ -40,7 +40,7 @@ static int send_rrlp_req(struct gsm_subscriber_connection *conn) { - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; const uint8_t *req; switch (net->rrlp.mode) { diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c index a750362..dba4bed 100644 --- a/openbsc/src/libmsc/transaction.c +++ b/openbsc/src/libmsc/transaction.c @@ -37,7 +37,7 @@ uint8_t proto, uint8_t trans_id) { struct gsm_trans *trans; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_subscriber *subscr = conn->subscr; llist_for_each_entry(trans, &net->trans_list, entry) { @@ -155,7 +155,7 @@ { struct gsm_trans *trans; - llist_for_each_entry(trans, &conn->bts->network->trans_list, entry) + llist_for_each_entry(trans, &conn->network->trans_list, entry) if (trans->conn == conn) return 1; -- To view, visit https://gerrit.osmocom.org/927 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I34537025986713291e14c8212a81539b497befd4 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 22 18:59:37 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 18:59:37 +0000 Subject: libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has restored this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:00:17 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:00:17 +0000 Subject: libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has restored this change. Change subject: gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:04:21 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:04:21 +0000 Subject: [ABANDON] libosmocore[master]: gsm/gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm/gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/841 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I392725fc62e7d29c17f82cf0d544f22700c25dbc Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:05:11 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:05:11 +0000 Subject: [ABANDON] libosmocore[master]: gsm0503: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: gsm0503: migrate transcoding routines from OsmoBTS ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/816 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I257a5d015798ee9e690fd035ca97fd971cf9f60a Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:08:09 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 19:08:09 +0000 Subject: [ABANDON] osmo-iuh[master]: log hnbap UE context allocation In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: log hnbap UE context allocation ...................................................................... Abandoned not ready yet -- To view, visit https://gerrit.osmocom.org/911 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I572095e6d3f2b48362bf8a88bc66f8438348d29a Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:08:56 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:08:56 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: generate a single file In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/828 to look at the new patch set (#4). utils/conv_gen.py: generate a single file Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa --- M .gitignore M src/gsm/Makefile.am M utils/conv_gen.py 3 files changed, 309 insertions(+), 316 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/828/4 diff --git a/.gitignore b/.gitignore index 5165364..90c8c85 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,7 @@ doc/*.tag src/crc*gen.c -src/gsm/conv*gen.c +src/gsm/gsm0503_conv.c include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index a2f2524..9a9d96f 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -18,16 +18,11 @@ gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \ lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \ - conv_cs2_gen.c conv_cs3_gen.c conv_xcch_gen.c \ - conv_tch_afs_12_2_gen.c conv_tch_afs_10_2_gen.c \ - conv_tch_afs_7_95_gen.c conv_tch_afs_7_4_gen.c \ - conv_tch_afs_6_7_gen.c conv_tch_afs_5_9_gen.c \ - conv_tch_afs_5_15_gen.c conv_tch_afs_4_75_gen.c \ auth_core.c auth_comp128v1.c auth_comp128v23.c \ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c + gsup.c gprs_gea.c gsm0503_conv.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = ../libosmocore.la @@ -37,5 +32,6 @@ EXTRA_DIST = libosmogsm.map -conv%gen.c: ../../utils/conv_gen.py - $(AM_V_GEN)python2 ../../utils/conv_gen.py +# Convolutional codes generation +gsm0503_conv.c: + $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py diff --git a/utils/conv_gen.py b/utils/conv_gen.py index a4f918f..38ea63b 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -222,325 +222,322 @@ ( G1, 1 ), ] -# xCCH definition -xCCH = ConvolutionalCode( - 224, - CCH_poly, - name = "xcch", - description = [ - "xCCH convolutional code:", - "228 bits blocks, rate 1/2, k = 5", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) +conv_codes = [ + # xCCH definition + ConvolutionalCode( + 224, + CCH_poly, + name = "xcch", + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS2 definition -CS2 = ConvolutionalCode( - 290, - CCH_poly, - puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], - name = "cs2", - description = [ - "CS2 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS2 definition + ConvolutionalCode( + 290, + CCH_poly, + puncture = [ + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], + name = "cs2", + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# CS3 definition -CS3 = ConvolutionalCode( - 334, - CCH_poly, - puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], - name = "cs3", - description = [ - "CS3 convolutional code:", - "G0 = 1 + D3 + D4", - "G1 = 1 + D + D3 + D4", - ] -) + # CS3 definition + ConvolutionalCode( + 334, + CCH_poly, + puncture = [ + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], + name = "cs3", + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] + ), -# TCH_AFS_12_2 definition -TCH_AFS_12_2 = ConvolutionalCode( - 250, - [ - ( 1, 1 ), - ( G1, G0 ), - ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], - name = 'tch_afs_12_2', - description = [ - "TCH/AFS 12.2 kbits convolutional code:", - "250 bits block, rate 1/2, punctured", - "G0/G0 = 1", - "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", - ] -) + # TCH_AFS_12_2 definition + ConvolutionalCode( + 250, + [ + ( 1, 1 ), + ( G1, G0 ), + ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], + name = 'tch_afs_12_2', + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] + ), -# TCH_AFS_10_2 definition -TCH_AFS_10_2 = ConvolutionalCode( - 210, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], - name = 'tch_afs_10_2', - description = [ - "TCH/AFS 10.2 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_10_2 definition + ConvolutionalCode( + 210, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], + name = 'tch_afs_10_2', + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_7_95 definition -TCH_AFS_7_95 = ConvolutionalCode( - 165, - [ - ( 1, 1 ), - ( G5, G4 ), - ( G6, G4 ), - ], - puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], - name = 'tch_afs_7_95', - description = [ - "TCH/AFS 7.95 kbits convolutional code:", - "G4/G4 = 1", - "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", - "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", - ] -) + # TCH_AFS_7_95 definition + ConvolutionalCode( + 165, + [ + ( 1, 1 ), + ( G5, G4 ), + ( G6, G4 ), + ], + puncture = [ + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], + name = 'tch_afs_7_95', + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] + ), -# TCH_AFS_7_4 definition -TCH_AFS_7_4 = ConvolutionalCode( - 154, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ], - puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], - name = 'tch_afs_7_4', - description = [ - "TCH/AFS 7.4 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - ] -) + # TCH_AFS_7_4 definition + ConvolutionalCode( + 154, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ], + puncture = [ + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], + name = 'tch_afs_7_4', + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] + ), -# TCH_AFS_6_7 definition -TCH_AFS_6_7 = ConvolutionalCode( - 140, - [ - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], - name = 'tch_afs_6_7', - description = [ - "TCH/AFS 6.7 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_6_7 definition + ConvolutionalCode( + 140, + [ + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], + name = 'tch_afs_6_7', + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_5_9 definition -TCH_AFS_5_9 = ConvolutionalCode( - 124, - [ - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1), - ( 1, 1), - ], - puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], - name = 'tch_afs_5_9', - description = [ - "TCH/AFS 5.9 kbits convolutional code:", - "124 bits", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_5_9 definition + ConvolutionalCode( + 124, + [ + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1), + ( 1, 1), + ], + puncture = [ + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], + name = 'tch_afs_5_9', + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ), -# TCH_AFS_5_15 definition -TCH_AFS_5_15 = ConvolutionalCode( - 109, - [ - ( G1, G3 ), - ( G1, G3 ), - ( G2, G3 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], - name = 'tch_afs_5_15', - description = [ - "TCH/AFS 5.15 kbits convolutional code:", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", - "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", - "G3/G3 = 1", - "G3/G3 = 1", - ] -) + # TCH_AFS_5_15 definition + ConvolutionalCode( + 109, + [ + ( G1, G3 ), + ( G1, G3 ), + ( G2, G3 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], + name = 'tch_afs_5_15', + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] + ), -# TCH_AFS_4_75 definition -TCH_AFS_4_75 = ConvolutionalCode( - 101, - [ - ( G4, G6 ), - ( G4, G6 ), - ( G5, G6 ), - ( 1, 1 ), - ( 1, 1 ), - ], - puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], - name = 'tch_afs_4_75', - description = [ - "TCH/AFS 4.75 kbits convolutional code:", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", - "G6/G6 = 1", - "G6/G6 = 1", - ] -) + # TCH_AFS_4_75 definition + ConvolutionalCode( + 101, + [ + ( G4, G6 ), + ( G4, G6 ), + ( G5, G6 ), + ( 1, 1 ), + ( 1, 1 ), + ], + puncture = [ + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], + name = 'tch_afs_4_75', + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] + ) +] -def gen_c(dest, pref, code): - f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w') +if __name__ == '__main__': + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + prefix = "gsm0503" + + print >>sys.stderr, "Generating convolutional codes..." + + # Open a new file for writing + f = open(os.path.join(path, "gsm0503_conv.c"), 'w') print >>f, mod_license print >>f, "#include " print >>f, "#include " - code.gen_tables(pref, f) -if __name__ == '__main__': - print >>sys.stderr, "Generating convolutional codes..." - prefix = "gsm0503" - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - gen_c(path, prefix, xCCH) - gen_c(path, prefix, CS2) - gen_c(path, prefix, CS3) - gen_c(path, prefix, TCH_AFS_12_2) - gen_c(path, prefix, TCH_AFS_10_2) - gen_c(path, prefix, TCH_AFS_7_95) - gen_c(path, prefix, TCH_AFS_7_4) - gen_c(path, prefix, TCH_AFS_6_7) - gen_c(path, prefix, TCH_AFS_5_9) - gen_c(path, prefix, TCH_AFS_5_15) - gen_c(path, prefix, TCH_AFS_4_75) - print >>sys.stderr, "\tdone." + # Generate the tables one by one + for code in conv_codes: + print >>sys.stderr, "Generate '%s' definition" % code.name + code.gen_tables(prefix, f) + + print >>sys.stderr, "Generation complete." -- To view, visit https://gerrit.osmocom.org/828 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib4e4ee5fdde38429e68e3b2fa50ec03a18f59daa Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:08:56 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:08:56 +0000 Subject: [PATCH] libosmocore[master]: utils/conv_gen.py: improve output formatting In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/829 to look at the new patch set (#3). utils/conv_gen.py: improve output formatting Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c --- M src/gsm/Makefile.am M utils/conv_gen.py 2 files changed, 43 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/29/829/3 diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 9a9d96f..d367c89 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -35,3 +35,5 @@ # Convolutional codes generation gsm0503_conv.c: $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py + +CLEANFILES = gsm0503_conv.c diff --git a/utils/conv_gen.py b/utils/conv_gen.py index 38ea63b..5a519bc 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -129,17 +129,30 @@ return ns, nb def _print_term(self, fi, num_states, pack = False): + # Up to 12 numbers should be placed per line + counter = 0 d = [] + for state in range(num_states): if pack: x = pack(self.next_term_output(state)) else: x = self.next_term_state(state) - d.append("%d, " % x) - print >>fi, "\t%s" % ''.join(d) + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % x) + counter += 1 + + fi.write("\n") def _print_x(self, fi, num_states, pack = False): + # Up to 4 blocks should be placed per line + counter = 0 + for state in range(num_states): if pack: x0 = pack(self.next_output(state, 0)) @@ -148,7 +161,30 @@ x0 = self.next_state(state, 0) x1 = self.next_state(state, 1) - print >>fi, "\t{ %2d, %2d }," % (x0, x1) + if counter == 0: + fi.write("\t") + elif counter % 4 == 0: + fi.write("\n\t") + + fi.write("{ %2d, %2d }, " % (x0, x1)) + counter += 1 + + fi.write("\n") + + def _print_puncture(self, fi): + # Up to 12 numbers should be placed per line + counter = 0 + + for p in self.puncture: + if counter == 0: + fi.write("\t") + elif counter % 12 == 0: + fi.write("\n\t") + + fi.write("%3d, " % p) + counter += 1 + + fi.write("\n") def gen_tables(self, pref, fi): pack = lambda n: \ @@ -173,10 +209,10 @@ self._print_term(fi, num_states, pack) print >>fi, "};" + # Write puncture if preset if len(self.puncture): print >>fi, "\nstatic const int %s_puncture[] = {" % self.name - for p in self.puncture: - print >>fi, "\t%d," % p + self._print_puncture(fi) print >>fi, "};" # Write description as a multi-line comment -- To view, visit https://gerrit.osmocom.org/829 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I95256c4ad402a3c088bdb6c5a5cda8b17c31881c Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:08:57 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Thu, 22 Sep 2016 19:08:57 +0000 Subject: [PATCH] libosmocore[master]: libosmocoding: migrate transcoding routines from OsmoBTS Message-ID: Review at https://gerrit.osmocom.org/933 libosmocoding: migrate transcoding routines from OsmoBTS There are some projects, such as GR-GSM and OsmocomBB, which would benefit from using one shared implementation of GSM 05.03 code. So, this commit introduces a new sub-library called libosmocoding, which (for now) provides GSM, GPRS and EDGE transcoding routines, migrated from OsmoBTS. The original GSM 05.03 code from OsmoBTS was relicensed under GPLv2-or-later with permission of copyright holders (Andreas Eversberg, Alexander Chemeris and Tom Tsou). The following data types are currently supported: - xCCH - PDTCH (CS 2,3 and MCS 1-9) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 --- A Doxyfile.coding.in M Makefile.am M configure.ac M debian/control M include/Makefile.am A include/osmocom/coding/gsm0503_coding.h A include/osmocom/coding/gsm0503_interleaving.h A include/osmocom/coding/gsm0503_mapping.h A include/osmocom/coding/gsm0503_parity.h A include/osmocom/coding/gsm0503_tables.h A libosmocoding.pc.in A src/coding/Makefile.am A src/coding/gsm0503_coding.c A src/coding/gsm0503_interleaving.c A src/coding/gsm0503_mapping.c A src/coding/gsm0503_parity.c A src/coding/gsm0503_tables.c M src/gsm/libosmogsm.map 18 files changed, 7,506 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/933/1 -- To view, visit https://gerrit.osmocom.org/933 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Thu Sep 22 19:11:46 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 22 Sep 2016 19:11:46 +0000 Subject: [PATCH] openbsc[master]: cosmetic fixes in libcommon/talloc_ctx.c In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/919 to look at the new patch set (#2). cosmetic fixes in libcommon/talloc_ctx.c Add copyright notice, remove obsolete include, remove unneeded line break. Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 --- M openbsc/src/libcommon/talloc_ctx.c 1 file changed, 21 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/19/919/2 diff --git a/openbsc/src/libcommon/talloc_ctx.c b/openbsc/src/libcommon/talloc_ctx.c index ae6a156..528d3a2 100644 --- a/openbsc/src/libcommon/talloc_ctx.c +++ b/openbsc/src/libcommon/talloc_ctx.c @@ -1,6 +1,25 @@ -#include -#include +/* OpenBSC allocation contexts initialization code */ +/* (C) 2011-2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * 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 . + * + */ +#include + +extern void *tall_bsc_ctx; extern void *tall_msgb_ctx; extern void *tall_fle_ctx; extern void *tall_locop_ctx; -- To view, visit https://gerrit.osmocom.org/919 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:56:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:56:27 +0000 Subject: openbsc[master]: cosmetic fixes in libcommon/talloc_ctx.c In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/919 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:56:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:56:42 +0000 Subject: osmo-iuh[master]: comment: note RAB assignment spec reference In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/912 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifef8da82a01cd781ef560d1ec21cbfb23efb1495 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:56:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:56:46 +0000 Subject: [MERGED] osmo-iuh[master]: comment: note RAB assignment spec reference In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: comment: note RAB assignment spec reference ...................................................................... comment: note RAB assignment spec reference Change-Id: Ifef8da82a01cd781ef560d1ec21cbfb23efb1495 --- M src/ranap_msg_factory.c 1 file changed, 4 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 94eb1c5..16a9d03 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -705,7 +705,10 @@ id->bits_unused = 0; } -/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */ +/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice). + * See 3GPP TS 25.413 8.2. + * RAB ID: 3GPP TS 25.413 9.2.1.2 + */ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port, bool use_x213_nsap) -- To view, visit https://gerrit.osmocom.org/912 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifef8da82a01cd781ef560d1ec21cbfb23efb1495 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:56:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:56:58 +0000 Subject: [MERGED] openbsc[master]: cosmetic fixes in libcommon/talloc_ctx.c In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: cosmetic fixes in libcommon/talloc_ctx.c ...................................................................... cosmetic fixes in libcommon/talloc_ctx.c Add copyright notice, remove obsolete include, remove unneeded line break. Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 --- M openbsc/src/libcommon/talloc_ctx.c 1 file changed, 21 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libcommon/talloc_ctx.c b/openbsc/src/libcommon/talloc_ctx.c index ae6a156..528d3a2 100644 --- a/openbsc/src/libcommon/talloc_ctx.c +++ b/openbsc/src/libcommon/talloc_ctx.c @@ -1,6 +1,25 @@ -#include -#include +/* OpenBSC allocation contexts initialization code */ +/* (C) 2011-2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * 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 . + * + */ +#include + +extern void *tall_bsc_ctx; extern void *tall_msgb_ctx; extern void *tall_fle_ctx; extern void *tall_locop_ctx; -- To view, visit https://gerrit.osmocom.org/919 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4d06a0323aee5a003b06edd179fc61e1936acae5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:58:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:58:13 +0000 Subject: osmo-bts[master]: DTX: fix last SID saving In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 01:59:44 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 01:59:44 +0000 Subject: osmo-bts[master]: DTX: fix SID repeat scheduling In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/857 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:00:44 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:00:44 +0000 Subject: osmo-bts[master]: DTX: fix SID logic In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/858 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:02:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:02:33 +0000 Subject: osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Patch Set 8: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/691/8/src/common/l1sap.c File src/common/l1sap.c: Line 695: marker = resp_msg->cb[0]; please wrap cb[] access into a nice macro, like rtpmsg_marker_bit(x) (x)->cb[0] and use that both to set the bit "rtpmsg_marker_bit(msg) = 1" and to check for the bit here. -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:03:05 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:03:05 +0000 Subject: osmo-bts[master]: lc15, sysmo: Use SID_FIRST_P1 to initiate DTX In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/692 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:03:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:03:58 +0000 Subject: libosmocore[master]: libosmocoding: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/933 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:05:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:05:47 +0000 Subject: osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 it might be worth noting explicitly in the code (comment) and in the commit message, that this is a non-standard (spec violating) behavior observed by certain ip.access nano3G products, and we're merely working around that. At least that's my understanding of what it is? Maybe I reember the spec wrong? -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:06:29 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:06:29 +0000 Subject: osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 ok, you did that in a follow-up commit. fine. -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:08:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:08:20 +0000 Subject: osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 as this is a non-standard quirk, I would recommend to add a vty config option to it. The default should be standard behavior. Only if the user requests the non-standard behavior using 'hnbap-accept-tmsi-in-uereg 1' it would be enabled? -- To view, visit https://gerrit.osmocom.org/910 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:09:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:09:06 +0000 Subject: osmo-bts[master]: octphy: Fixing missing payload type in ph. chan. activation In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/900 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:11:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:11:28 +0000 Subject: osmo-bts[master]: rsl: improved log output In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (2 comments) https://gerrit.osmocom.org/#/c/902/1/src/common/rsl.c File src/common/rsl.c: Line 1436: /* locally bound IP */ this changes the order of IEs in the RSL message, whcih I don't think is a good idea. The rlated change should be reverted, or split into a separate patch Line 1589: LOGP(DRSL, LOGL_NOTICE, "connect_ip %d \n", connect_ip ); these logging related changes are fine with me. but not the IE re-ordering above. -- To view, visit https://gerrit.osmocom.org/902 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:12:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:12:56 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Fixing band selection for ARFCN 0 In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/903 to look at the new patch set (#2). octphy: Fixing band selection for ARFCN 0 There is now an exception for ARFCN 0 in osmocom_to_octphy_band to distingush ARFCN 0 (E-GSM) and 1-124 (P-GSM). Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/03/903/2 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index d621bcf..c4105ac 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -98,7 +98,9 @@ case GSM_BAND_850: return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_850; case GSM_BAND_900: - if (arfcn >= 955 && arfcn <= 974) + if (arfcn == 0) + return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; + else if (arfcn >= 955 && arfcn <= 974) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_R_900; else if (arfcn >= 975 && arfcn <= 1023) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; -- To view, visit https://gerrit.osmocom.org/903 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:13:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:13:02 +0000 Subject: osmo-bts[master]: octphy: Fixing band selection for ARFCN 0 In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/903/1/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 101: if (arfcn == 0) space before '(' required, 'if' is not a function call. -- To view, visit https://gerrit.osmocom.org/903 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:14:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:14:27 +0000 Subject: osmo-bts[master]: octphy: set tx attenuation via VTY In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 the flag is set, but I don't see the flag ever being used anywhere? -- To view, visit https://gerrit.osmocom.org/905 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:15:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:15:34 +0000 Subject: osmo-bts[master]: octphy: Fixed OML ADM state handling In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/906/1/src/osmo-bts-octphy/l1_oml.c File src/osmo-bts-octphy/l1_oml.c: Line 1360: oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; this belongs into the previous patch -- To view, visit https://gerrit.osmocom.org/906 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:16:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:16:47 +0000 Subject: osmo-bts[master]: octphy: Dont't crash if transceiver is re-initalized In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 the question is whether this is a valid operation or not. My assumption was that we should always close all transceivers and then open them, to ensure all state is re-set. Please discuss/re-confirm with octasic. -- To view, visit https://gerrit.osmocom.org/907 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3fccc8e45843d255b256a753547436c39bbf38b0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:17 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:17 +0000 Subject: libosmocore[master]: fix timer_test: don't forget to set tv_usec on the stop time In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/882 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I13bb60f7d341a397f95d13d9c63c40188b6cd5a0 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:26 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:26 +0000 Subject: libosmocore[master]: timer_test: also report early finishes, report timing on error In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/883 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id3942637d77a28b5092ffffcc3e6d9d67c2b8e68 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:40 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:40 +0000 Subject: libosmocore[master]: timer_test: remove unused precision values and confusing log In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/884 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:46 +0000 Subject: libosmocore[master]: add osmo_gettimeofday as a shim around gettimeofday In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/885 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:53 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:53 +0000 Subject: libosmocore[master]: timer_test: do not use real time: deterministic and faster In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/886 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:17:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:17:58 +0000 Subject: libosmocore[master]: timer_test: remove all random elements In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/887 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9833031407e99f5d7a1144c26b68a7e320b2020d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:02 +0000 Subject: libosmocore[master]: timer_test: redirect some output from stderr to stdout In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/888 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia3bba1c650be3558d370e0f59d4ee7f36ef97506 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:07 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:07 +0000 Subject: libosmocore[master]: timer_test: print more details to stdout to check In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/889 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iecf6387f1d25253fcf1260777673853030c1d326 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:11 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:11 +0000 Subject: libosmocore[master]: timer_test: set 8 as default steps, use the default in tests... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/890 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5070578e9fe2bdacaad000eaafb8dc5f549d6f3e Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:15 +0000 Subject: [MERGED] libosmocore[master]: timer_test: set 8 as default steps, use the default in tests... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: set 8 as default steps, use the default in testsuite.at ...................................................................... timer_test: set 8 as default steps, use the default in testsuite.at Change-Id: I5070578e9fe2bdacaad000eaafb8dc5f549d6f3e --- M tests/testsuite.at M tests/timer/timer_test.c M tests/timer/timer_test.ok 3 files changed, 281 insertions(+), 16 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/testsuite.at b/tests/testsuite.at index 0c7edf1..2f274f9 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -193,7 +193,7 @@ AT_SETUP([timer]) AT_KEYWORDS([timer]) cat $abs_srcdir/timer/timer_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/timer/timer_test -s 5], [0], [expout], [ignore]) +AT_CHECK([$abs_top_builddir/tests/timer/timer_test], [0], [expout], [ignore]) AT_CLEANUP AT_SETUP([tlv]) diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index ec85c04..066dc72 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -54,7 +54,7 @@ }; /* number of test steps. We add fact(steps) timers in the whole test. */ -#define MAIN_TIMER_NSTEPS 16 +#define MAIN_TIMER_NSTEPS 8 /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 109d039..75b11c7 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,4 +1,4 @@ -Running timer test for 5 iterations, 85 steps of 423 msecs each +Running timer test for 8 iterations, 66 steps of 423 msecs each 23.424242 23.847452 24.270662 @@ -72,34 +72,299 @@ early deleted 4 timers, 13 still active 31.042022 main_timer_fired() -Main timer has finished, please, wait a bit for the final report. +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +scheduled timer at 32.042022 +scheduled timer at 33.042022 +scheduled timer at 34.042022 +scheduled timer at 35.042022 +scheduled timer at 36.042022 +scheduled timer at 37.042022 +scheduled timer at 38.042022 +scheduled timer at 39.042022 +added 32 timers in step 5 (expired=18) 31.465232 timer fired on time: 31.233132 (+ 0.232100) -early deleted 3 timers, 9 still active +early deleted 11 timers, 33 still active 31.888442 timer fired on time: 31.772392 (+ 0.116050) -early deleted 2 timers, 6 still active +early deleted 8 timers, 24 still active 32.311652 +main_timer_fired() +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +scheduled timer at 33.311652 +scheduled timer at 34.311652 +scheduled timer at 35.311652 +scheduled timer at 36.311652 +scheduled timer at 37.311652 +scheduled timer at 38.311652 +scheduled timer at 39.311652 +scheduled timer at 40.311652 +added 64 timers in step 6 (expired=39) 32.734862 33.158072 -timer fired on time: 32.772392 (+ 0.385680) -early deleted 1 timers, 4 still active +timer fired on time: 33.042022 (+ 0.116050) +early deleted 21 timers, 66 still active +timer fired on time: 33.042022 (+ 0.116050) +early deleted 16 timers, 49 still active 33.581282 +main_timer_fired() +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +scheduled timer at 34.581282 +scheduled timer at 35.581282 +scheduled timer at 36.581282 +scheduled timer at 37.581282 +scheduled timer at 38.581282 +scheduled timer at 39.581282 +scheduled timer at 40.581282 +scheduled timer at 41.581282 +added 128 timers in step 7 (expired=78) 34.004492 34.427702 +timer fired on time: 34.311652 (+ 0.116050) +early deleted 44 timers, 132 still active +timer fired on time: 34.311652 (+ 0.116050) +early deleted 32 timers, 99 still active +timer fired on time: 34.311652 (+ 0.116050) +early deleted 24 timers, 74 still active 34.850912 +main_timer_fired() +Main timer has finished, please, wait a bit for the final report. 35.274122 35.697332 +timer fired on time: 35.581282 (+ 0.116050) +early deleted 18 timers, 55 still active +timer fired on time: 35.581282 (+ 0.116050) +early deleted 13 timers, 41 still active +timer fired on time: 35.581282 (+ 0.116050) +early deleted 10 timers, 30 still active 36.120542 -timer fired on time: 35.772392 (+ 0.348150) -early deleted 0 timers, 3 still active 36.543752 -timer fired on time: 36.502762 (+ 0.040990) -early deleted 0 timers, 2 still active +timer fired on time: 36.311652 (+ 0.232100) +early deleted 7 timers, 22 still active +timer fired on time: 36.311652 (+ 0.232100) +early deleted 5 timers, 16 still active 36.966962 -timer fired on time: 36.772392 (+ 0.194570) -early deleted 0 timers, 1 still active +timer fired on time: 36.581282 (+ 0.385680) +early deleted 3 timers, 12 still active 37.390172 +timer fired on time: 37.042022 (+ 0.348150) +early deleted 2 timers, 9 still active 37.813382 -timer fired on time: 37.772392 (+ 0.040990) -test over: added=31 expired=31 too_soon=0 too_late=0 +timer fired on time: 37.581282 (+ 0.232100) +early deleted 2 timers, 6 still active +38.236592 +38.659802 +39.083012 +39.506222 +timer fired on time: 39.311652 (+ 0.194570) +early deleted 1 timers, 4 still active +39.929432 +timer fired on time: 39.581282 (+ 0.348150) +early deleted 0 timers, 3 still active +40.352642 +40.775852 +timer fired on time: 40.581282 (+ 0.194570) +early deleted 0 timers, 2 still active +41.199062 +41.622272 +timer fired on time: 41.581282 (+ 0.040990) +early deleted 0 timers, 1 still active +timer fired on time: 41.581282 (+ 0.040990) +test over: added=255 expired=255 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/890 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5070578e9fe2bdacaad000eaafb8dc5f549d6f3e Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:15 +0000 Subject: [MERGED] libosmocore[master]: timer_test: print more details to stdout to check In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: print more details to stdout to check ...................................................................... timer_test: print more details to stdout to check The test is now fully deterministic, so include all detail in stdout, to check for. Change-Id: Iecf6387f1d25253fcf1260777673853030c1d326 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 116 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 12caecf..ec85c04 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -73,6 +73,7 @@ unsigned int *step = data; unsigned int add_in_this_step; int i; + printf("main_timer_fired()\n"); if (*step == timer_nsteps) { printf("Main timer has finished, please, " @@ -98,6 +99,8 @@ v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); + printf("scheduled timer at %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec); } printf("added %d timers in step %u (expired=%u)\n", add_in_this_step, *step, expired_timers); @@ -111,7 +114,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res; struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; - int i; + int i, deleted; osmo_gettimeofday(¤t, NULL); @@ -132,6 +135,10 @@ (int)res.tv_sec, (int)res.tv_usec); too_soon++; } + else + printf("timer fired on time: %d.%06d (+ %d.%06d)\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); llist_del(&v->head); talloc_free(data); @@ -144,15 +151,19 @@ /* "random" deletion of timers. */ i = 0; + deleted = 0; llist_for_each_entry_safe(this, tmp, &timer_test_list, head) { i ++; if (!(i & 0x3)) { osmo_timer_del(&this->timer); llist_del(&this->head); talloc_free(this); - expired_timers++; + deleted++; } } + expired_timers += deleted; + printf("early deleted %d timers, %d still active\n", deleted, + total_timers - expired_timers); } int main(int argc, char *argv[]) @@ -180,12 +191,16 @@ steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) / TIME_BETWEEN_TIMER_CHECKS; - printf("Running timer test for %u steps\n", timer_nsteps); + printf("Running timer test for %d iterations," + " %d steps of %d msecs each\n", + timer_nsteps, steps, TIME_BETWEEN_TIMER_CHECKS / 1000); osmo_timer_schedule(&main_timer, 1, 0); #ifdef HAVE_SYS_SELECT_H while (steps--) { + printf("%d.%06d\n", (int)osmo_gettimeofday_override_time.tv_sec, + (int)osmo_gettimeofday_override_time.tv_usec); osmo_timers_prepare(); osmo_timers_update(); osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 7617bc3..109d039 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,8 +1,105 @@ -Running timer test for 5 steps +Running timer test for 5 iterations, 85 steps of 423 msecs each +23.424242 +23.847452 +24.270662 +24.693872 +main_timer_fired() +scheduled timer at 25.693872 added 1 timers in step 0 (expired=0) +25.117082 +25.540292 +25.963502 +main_timer_fired() +scheduled timer at 26.963502 +scheduled timer at 27.963502 added 2 timers in step 1 (expired=0) +timer fired on time: 25.693872 (+ 0.269630) +early deleted 0 timers, 2 still active +26.386712 +26.809922 +27.233132 +main_timer_fired() +scheduled timer at 28.233132 +scheduled timer at 29.233132 +scheduled timer at 30.233132 +scheduled timer at 31.233132 added 4 timers in step 2 (expired=1) +timer fired on time: 26.963502 (+ 0.269630) +early deleted 1 timers, 4 still active +27.656342 +28.079552 +timer fired on time: 27.963502 (+ 0.116050) +early deleted 0 timers, 3 still active +28.502762 +main_timer_fired() +scheduled timer at 29.502762 +scheduled timer at 30.502762 +scheduled timer at 31.502762 +scheduled timer at 32.502762 +scheduled timer at 33.502762 +scheduled timer at 34.502762 +scheduled timer at 35.502762 +scheduled timer at 36.502762 added 8 timers in step 3 (expired=4) +28.925972 +29.349182 +timer fired on time: 29.233132 (+ 0.116050) +early deleted 2 timers, 8 still active +29.772392 +main_timer_fired() +scheduled timer at 30.772392 +scheduled timer at 31.772392 +scheduled timer at 32.772392 +scheduled timer at 33.772392 +scheduled timer at 34.772392 +scheduled timer at 35.772392 +scheduled timer at 36.772392 +scheduled timer at 37.772392 +scheduled timer at 30.772392 +scheduled timer at 31.772392 +scheduled timer at 32.772392 +scheduled timer at 33.772392 +scheduled timer at 34.772392 +scheduled timer at 35.772392 +scheduled timer at 36.772392 +scheduled timer at 37.772392 added 16 timers in step 4 (expired=7) +30.195602 +30.618812 +timer fired on time: 30.502762 (+ 0.116050) +early deleted 5 timers, 18 still active +timer fired on time: 30.233132 (+ 0.385680) +early deleted 4 timers, 13 still active +31.042022 +main_timer_fired() Main timer has finished, please, wait a bit for the final report. +31.465232 +timer fired on time: 31.233132 (+ 0.232100) +early deleted 3 timers, 9 still active +31.888442 +timer fired on time: 31.772392 (+ 0.116050) +early deleted 2 timers, 6 still active +32.311652 +32.734862 +33.158072 +timer fired on time: 32.772392 (+ 0.385680) +early deleted 1 timers, 4 still active +33.581282 +34.004492 +34.427702 +34.850912 +35.274122 +35.697332 +36.120542 +timer fired on time: 35.772392 (+ 0.348150) +early deleted 0 timers, 3 still active +36.543752 +timer fired on time: 36.502762 (+ 0.040990) +early deleted 0 timers, 2 still active +36.966962 +timer fired on time: 36.772392 (+ 0.194570) +early deleted 0 timers, 1 still active +37.390172 +37.813382 +timer fired on time: 37.772392 (+ 0.040990) test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/889 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iecf6387f1d25253fcf1260777673853030c1d326 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:15 +0000 Subject: [MERGED] libosmocore[master]: timer_test: redirect some output from stderr to stdout In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: redirect some output from stderr to stdout ...................................................................... timer_test: redirect some output from stderr to stdout This way we can check the output in timer_test.ok. Change-Id: Ia3bba1c650be3558d370e0f59d4ee7f36ef97506 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 24 insertions(+), 20 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index d8e1ec9..12caecf 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -75,8 +75,8 @@ int i; if (*step == timer_nsteps) { - fprintf(stderr, "Main timer has finished, please, " - "wait a bit for the final report.\n"); + printf("Main timer has finished, please, " + "wait a bit for the final report.\n"); return; } /* add 2^step pair of timers per step. */ @@ -87,7 +87,7 @@ v = talloc_zero(NULL, struct test_timer); if (v == NULL) { - fprintf(stderr, "timer_test: OOM!\n"); + printf("timer_test: OOM!\n"); return; } osmo_gettimeofday(&v->start, NULL); @@ -99,7 +99,7 @@ osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); } - fprintf(stderr, "added %d timers in step %u (expired=%u)\n", + printf("added %d timers in step %u (expired=%u)\n", add_in_this_step, *step, expired_timers); total_timers += add_in_this_step; osmo_timer_schedule(&main_timer, TIME_BETWEEN_STEPS, 0); @@ -117,21 +117,19 @@ timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { - fprintf(stderr, "ERROR: timer has expired too late:" - " wanted %d.%06d now %d.%06d diff %d.%06d\n", - (int)v->stop.tv_sec, (int)v->stop.tv_usec, - (int)current.tv_sec, (int)current.tv_usec, - (int)res.tv_sec, (int)res.tv_usec - ); + printf("ERROR: timer has expired too late:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); too_late++; } else if (timercmp(¤t, &v->stop, <)) { - fprintf(stderr, "ERROR: timer has expired too soon:" - " wanted %d.%06d now %d.%06d diff %d.%06d\n", - (int)v->stop.tv_sec, (int)v->stop.tv_usec, - (int)current.tv_sec, (int)current.tv_usec, - (int)res.tv_sec, (int)res.tv_usec - ); + printf("ERROR: timer has expired too soon:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec); too_soon++; } @@ -139,8 +137,8 @@ talloc_free(data); expired_timers++; if (expired_timers == total_timers) { - fprintf(stdout, "test over: added=%u expired=%u too_soon=%u too_late=%u\n", - total_timers, expired_timers, too_soon, too_late); + printf("test over: added=%u expired=%u too_soon=%u too_late=%u\n", + total_timers, expired_timers, too_soon, too_late); exit(EXIT_SUCCESS); } @@ -182,7 +180,7 @@ steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) / TIME_BETWEEN_TIMER_CHECKS; - fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); + printf("Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); @@ -193,7 +191,7 @@ osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); } #else - fprintf(stdout, "Select not supported on this platform!\n"); + printf("Select not supported on this platform!\n"); #endif return 0; } diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 22b93aa..7617bc3 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,8 @@ Running timer test for 5 steps +added 1 timers in step 0 (expired=0) +added 2 timers in step 1 (expired=0) +added 4 timers in step 2 (expired=1) +added 8 timers in step 3 (expired=4) +added 16 timers in step 4 (expired=7) +Main timer has finished, please, wait a bit for the final report. test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/888 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia3bba1c650be3558d370e0f59d4ee7f36ef97506 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: timer_test: remove all random elements In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: remove all random elements ...................................................................... timer_test: remove all random elements Change-Id: I9833031407e99f5d7a1144c26b68a7e320b2020d --- M tests/timer/timer_test.c 1 file changed, 6 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 461d060..d8e1ec9 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -93,7 +93,7 @@ osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; - unsigned int seconds = (random() % 10) + 1; + unsigned int seconds = (i & 0x7) + 1; v->stop.tv_sec = v->start.tv_sec + seconds; v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); @@ -111,6 +111,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res; struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; + int i; osmo_gettimeofday(¤t, NULL); @@ -143,9 +144,11 @@ exit(EXIT_SUCCESS); } - /* randomly (10%) deletion of timers. */ + /* "random" deletion of timers. */ + i = 0; llist_for_each_entry_safe(this, tmp, &timer_test_list, head) { - if ((random() % 100) < 10) { + i ++; + if (!(i & 0x3)) { osmo_timer_del(&this->timer); llist_del(&this->head); talloc_free(this); -- To view, visit https://gerrit.osmocom.org/887 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9833031407e99f5d7a1144c26b68a7e320b2020d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: timer_test: do not use real time: deterministic and faster In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: do not use real time: deterministic and faster ...................................................................... timer_test: do not use real time: deterministic and faster Use osmo_gettimeofday_override* to decouple the timer test from real time. No longer call osmo_select_main(), since select() actually waits for real time. This reduces the timer_test to the osmo_timer_* logic and excludes the real time and osmo_timers_nearest() accuracy testing with actual waiting involved. This may be seen as a loss, but is more fit for a test suite. The main point here is to get deterministic results in jenkins, so that we don't have to retrigger jobs based on timing failures; added bonus is that the test runs much faster now. Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 --- M tests/timer/timer_test.c 1 file changed, 15 insertions(+), 20 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 6308113..461d060 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,6 +59,9 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 +/* how much time elapses between checks, in microsecs */ +#define TIME_BETWEEN_TIMER_CHECKS 423210 + static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; static unsigned int total_timers = 0; @@ -106,7 +109,8 @@ static void secondary_timer_fired(void *data) { struct test_timer *v = data, *this, *tmp; - struct timeval current, res, precision = { 1, 0 }; + struct timeval current, res; + struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; osmo_gettimeofday(¤t, NULL); @@ -150,21 +154,12 @@ } } -static void alarm_handler(int signum) -{ - fprintf(stderr, "ERROR: We took too long to run the timer test, " - "something seems broken, aborting.\n"); - exit(EXIT_FAILURE); -} - int main(int argc, char *argv[]) { int c; + int steps; - if (signal(SIGALRM, alarm_handler) == SIG_ERR) { - perror("cannot register signal handler"); - exit(EXIT_FAILURE); - } + osmo_gettimeofday_override = true; while ((c = getopt_long(argc, argv, "s:", NULL, NULL)) != -1) { switch(c) { @@ -181,21 +176,21 @@ } } + steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) + / TIME_BETWEEN_TIMER_CHECKS; + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); - /* if the test takes too long, we may consider that the timer scheduler - * has hung. We set some maximum wait time which is the double of the - * maximum timeout randomly set (10 seconds, worst case) plus the - * number of steps (since some of them are reset each step). */ - alarm(2 * (10 + timer_nsteps)); - #ifdef HAVE_SYS_SELECT_H - while (1) { - osmo_select_main(0); + while (steps--) { + osmo_timers_prepare(); + osmo_timers_update(); + osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); } #else fprintf(stdout, "Select not supported on this platform!\n"); #endif + return 0; } -- To view, visit https://gerrit.osmocom.org/886 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic5649512df86dd17070daa2f314159eafaf8feb8 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: add osmo_gettimeofday as a shim around gettimeofday In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: add osmo_gettimeofday as a shim around gettimeofday ...................................................................... add osmo_gettimeofday as a shim around gettimeofday This allows feeding a custom time for unit tests by overriding osmo_gettimeofday. Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 --- M include/osmocom/core/timer.h M src/Makefile.am M src/gb/gprs_bssgp.c M src/gb/gprs_ns.c M src/logging.c M src/timer.c A src/timer_gettimeofday.c M src/vty/command.c M tests/gb/bssgp_fc_test.c M tests/timer/timer_test.c 10 files changed, 87 insertions(+), 17 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 6730bfe..dbda13f 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -29,6 +29,7 @@ #pragma once #include +#include #include #include @@ -83,4 +84,14 @@ int osmo_timers_update(void); int osmo_timers_check(void); +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz); + +/** + * timer override + */ + +extern bool osmo_gettimeofday_override; +extern struct timeval osmo_gettimeofday_override_time; +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs); + /*! @} */ diff --git a/src/Makefile.am b/src/Makefile.am index 7a6f464..74bdb21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = libosmocore.la libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) -libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \ +libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \ bitvec.c bitcomp.c statistics.c fsm.c \ write_queue.c utils.c socket.c \ logging.c logging_syslog.c rate_ctr.c \ diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 3ad2f29..1ee942f 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -603,7 +603,7 @@ fc->queue_depth--; /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; /* call the output callback for this FC instance */ @@ -688,7 +688,7 @@ /* compute number of centi-seconds that have elapsed since transmitting * the last PDU (Tc - Tp) */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); timersub(&time_now, &fc->time_last_pdu, &time_diff); csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000; @@ -747,7 +747,7 @@ return fc_enqueue(fc, msg, llc_pdu_len, priv); } else { /* record the time we transmitted this PDU */ - gettimeofday(&time_now, NULL); + osmo_gettimeofday(&time_now, NULL); fc->time_last_pdu = time_now; return fc->out_cb(priv, msg, llc_pdu_len, NULL); } @@ -766,7 +766,7 @@ fc->bucket_leak_rate = bucket_leak_rate; fc->max_queue_depth = max_queue_depth; INIT_LLIST_HEAD(&fc->queue); - gettimeofday(&fc->time_last_pdu, NULL); + osmo_gettimeofday(&fc->time_last_pdu, NULL); } /* Initialize the Flow Control parameters for a new MS according to diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 6879c70..18845d4 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -556,7 +556,7 @@ if (osmo_timer_pending(&nsvc->timer)) osmo_timer_del(&nsvc->timer); - gettimeofday(&nsvc->timer_started, NULL); + osmo_gettimeofday(&nsvc->timer_started, NULL); nsvc->timer_mode = mode; osmo_timer_schedule(&nsvc->timer, seconds, 0); } @@ -564,7 +564,7 @@ static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc) { struct timeval now, elapsed; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &nsvc->timer_started, &elapsed); return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000; diff --git a/src/logging.c b/src/logging.c index 8a10133..9e30d5f 100644 --- a/src/logging.c +++ b/src/logging.c @@ -44,6 +44,7 @@ #include #include #include +#include #include /* for LOGGING_STR. */ @@ -268,7 +269,7 @@ if (target->print_ext_timestamp) { struct tm tm; struct timeval tv; - gettimeofday(&tv, NULL); + osmo_gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &tm); ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, diff --git a/src/timer.c b/src/timer.c index 0358b89..10a0b95 100644 --- a/src/timer.c +++ b/src/timer.c @@ -91,7 +91,7 @@ { struct timeval current_time; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); timer->timeout.tv_sec = seconds; timer->timeout.tv_usec = microseconds; timeradd(&timer->timeout, ¤t_time, &timer->timeout); @@ -143,7 +143,7 @@ struct timeval current_time; if (!now) - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); else current_time = *now; @@ -193,7 +193,7 @@ struct rb_node *node; struct timeval current; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); node = rb_first(&timer_root); if (node) { @@ -214,7 +214,7 @@ struct osmo_timer_list *this; int work = 0; - gettimeofday(¤t_time, NULL); + osmo_gettimeofday(¤t_time, NULL); INIT_LLIST_HEAD(&timer_eviction_list); for (node = rb_first(&timer_root); node; node = rb_next(node)) { diff --git a/src/timer_gettimeofday.c b/src/timer_gettimeofday.c new file mode 100644 index 0000000..81a1598 --- /dev/null +++ b/src/timer_gettimeofday.c @@ -0,0 +1,58 @@ +/* + * (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Authors: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/*! \addtogroup timer + * @{ + */ + +/*! \file timer_gettimeofday.c + */ + +#include +#include + +bool osmo_gettimeofday_override = false; +struct timeval osmo_gettimeofday_override_time = { 23, 424242 }; + +/*! \brief shim around gettimeofday to be able to set the time manually. + * To override, set osmo_gettimeofday_override == true and set the desired + * current time in osmo_gettimeofday_override_time. */ +int osmo_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + if (osmo_gettimeofday_override) { + *tv = osmo_gettimeofday_override_time; + return 0; + } + + return gettimeofday(tv, tz); +} + +/*! \brief convenience function to advance the fake time. + * Add the given values to osmo_gettimeofday_override_time. */ +void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs) +{ + struct timeval val = { secs, usecs }; + timeradd(&osmo_gettimeofday_override_time, &val, + &osmo_gettimeofday_override_time); +} + +/*! @} */ diff --git a/src/vty/command.c b/src/vty/command.c index 483ca80..9d8bf31 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -637,7 +637,7 @@ struct timeval tv; char *crypt(const char *, const char *); - gettimeofday(&tv, 0); + osmo_gettimeofday(&tv, 0); to64(&salt[0], random(), 3); to64(&salt[3], tv.tv_usec, 3); diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c index ad8f83d..d77f141 100644 --- a/tests/gb/bssgp_fc_test.c +++ b/tests/gb/bssgp_fc_test.c @@ -22,7 +22,7 @@ { struct timeval tv; struct timeval now; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &tv_start, &tv); @@ -73,7 +73,7 @@ bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth, fc_out_cb); - gettimeofday(&tv_start, NULL); + osmo_gettimeofday(&tv_start, NULL); for (i = 0; i < pdu_count; i++) { fc_in(fc, pdu_len); diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 1aeab45..6308113 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -87,7 +87,7 @@ fprintf(stderr, "timer_test: OOM!\n"); return; } - gettimeofday(&v->start, NULL); + osmo_gettimeofday(&v->start, NULL); v->timer.cb = secondary_timer_fired; v->timer.data = v; unsigned int seconds = (random() % 10) + 1; @@ -108,7 +108,7 @@ struct test_timer *v = data, *this, *tmp; struct timeval current, res, precision = { 1, 0 }; - gettimeofday(¤t, NULL); + osmo_gettimeofday(¤t, NULL); timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { -- To view, visit https://gerrit.osmocom.org/885 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: timer_test: remove unused precision values and confusing log In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: remove unused precision values and confusing log ...................................................................... timer_test: remove unused precision values and confusing log Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 2 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index c576a04..1aeab45 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -59,10 +59,6 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 -/* timer imprecision that we accept for this test: 10 milliseconds. */ -#define TIMER_PRES_SECS 0 -#define TIMER_PRES_USECS 20000 - static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; static unsigned int total_timers = 0; @@ -185,9 +181,7 @@ } } - fprintf(stdout, "Running timer test for %u steps, accepting " - "imprecision of %u.%.6u seconds\n", - timer_nsteps, TIMER_PRES_SECS, TIMER_PRES_USECS); + fprintf(stdout, "Running timer test for %u steps\n", timer_nsteps); osmo_timer_schedule(&main_timer, 1, 0); diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 7c00000..22b93aa 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,2 @@ -Running timer test for 5 steps, accepting imprecision of 0.020000 seconds +Running timer test for 5 steps test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/884 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1570b7096c757d63d23e0950feeeb7230f8a5c9f Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: timer_test: also report early finishes, report timing on error In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: timer_test: also report early finishes, report timing on error ...................................................................... timer_test: also report early finishes, report timing on error When a timer was late, show the timing details. Also count whether timers fired early, for completeness' sake. Change-Id: Id3942637d77a28b5092ffffcc3e6d9d67c2b8e68 --- M tests/timer/timer_test.c M tests/timer/timer_test.ok 2 files changed, 19 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 4981fd5..c576a04 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -67,6 +67,7 @@ static unsigned int expired_timers = 0; static unsigned int total_timers = 0; static unsigned int too_late = 0; +static unsigned int too_soon = 0; static void main_timer_fired(void *data) { @@ -115,17 +116,30 @@ timersub(¤t, &v->stop, &res); if (timercmp(&res, &precision, >)) { - fprintf(stderr, "ERROR: timer %p has expired too late!\n", - &v->timer); + fprintf(stderr, "ERROR: timer has expired too late:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec + ); too_late++; + } + else if (timercmp(¤t, &v->stop, <)) { + fprintf(stderr, "ERROR: timer has expired too soon:" + " wanted %d.%06d now %d.%06d diff %d.%06d\n", + (int)v->stop.tv_sec, (int)v->stop.tv_usec, + (int)current.tv_sec, (int)current.tv_usec, + (int)res.tv_sec, (int)res.tv_usec + ); + too_soon++; } llist_del(&v->head); talloc_free(data); expired_timers++; if (expired_timers == total_timers) { - fprintf(stdout, "test over: added=%u expired=%u too_late=%u \n", - total_timers, expired_timers, too_late); + fprintf(stdout, "test over: added=%u expired=%u too_soon=%u too_late=%u\n", + total_timers, expired_timers, too_soon, too_late); exit(EXIT_SUCCESS); } diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 1bb382e..7c00000 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,2 +1,2 @@ Running timer test for 5 steps, accepting imprecision of 0.020000 seconds -test over: added=31 expired=31 too_late=0 +test over: added=31 expired=31 too_soon=0 too_late=0 -- To view, visit https://gerrit.osmocom.org/883 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id3942637d77a28b5092ffffcc3e6d9d67c2b8e68 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:16 +0000 Subject: [MERGED] libosmocore[master]: fix timer_test: don't forget to set tv_usec on the stop time In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: fix timer_test: don't forget to set tv_usec on the stop time ...................................................................... fix timer_test: don't forget to set tv_usec on the stop time The timer_test schedules timers and records the desired stop time. Also store the usec value of the desired stop time, because scheduling at e.g. sec N usec 999999 but recording sec N usec 0, and then receiving a timer at sec N+1 usec 0 is only 1 usec late, but records as 1000000 usecs late. This might have been the main cause of the timer test not working well on the osmocom build server. Change-Id: I13bb60f7d341a397f95d13d9c63c40188b6cd5a0 --- M tests/timer/timer_test.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index 6184f66..4981fd5 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -95,6 +95,7 @@ v->timer.data = v; unsigned int seconds = (random() % 10) + 1; v->stop.tv_sec = v->start.tv_sec + seconds; + v->stop.tv_usec = v->start.tv_usec; osmo_timer_schedule(&v->timer, seconds, 0); llist_add(&v->head, &timer_test_list); } -- To view, visit https://gerrit.osmocom.org/882 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I13bb60f7d341a397f95d13d9c63c40188b6cd5a0 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:18:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:18:42 +0000 Subject: libosmo-abis[master]: Use callback for polling data In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/864 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I11940cbf50361c4ea262d7001a16f9a982392f27 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:22:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:22:13 +0000 Subject: libosmo-abis[master]: Remove use of private oRTP function In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 if you do this, then you can remove the entire osmo_rtcp_fd_cb() function and make sure to set rs->rtcp_bfd.when = 0, while keeping rs->rtp_bfd.when = BSC_FD_READ. After all, why request the select() loop to wake you up to call a call-back function which then does nothing? I intentionally called the private libortp API as it was the only way that I could see to fully take advantage of select() based trigger for reading the RTCP socket and still processing the RTCP data. Maybe it is a bad idea and we should simply rely on the ortp internal polling of RTCP. But please make sure that the RTCP data is actually received before changing any part of this. -- To view, visit https://gerrit.osmocom.org/908 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:22:54 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:22:54 +0000 Subject: openbsc[master]: SNDCP: add SNDCP-XID encoder/decoder and unit test In-Reply-To: References: Message-ID: Patch Set 16: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/641 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e Gerrit-PatchSet: 16 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:23:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:23:20 +0000 Subject: openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Patch Set 19: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 19 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:26:55 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:26:55 +0000 Subject: openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Patch Set 39: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 39 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:30:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:30:27 +0000 Subject: openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Patch Set 6: Code-Review-1 (1 comment) sorry, one last request, and then we can finally merge it. thanks! https://gerrit.osmocom.org/#/c/803/6/openbsc/src/gprs/gprs_sndcp.c File openbsc/src/gprs/gprs_sndcp.c: Line 805: if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || you repeat those two lines in the if statement already five times in this single path. Please add an inline function so we can have an "if (any_pcomp_or_dcomp_active(sgsn))". -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:34:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:34:20 +0000 Subject: openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Patch Set 31: (1 comment) please check if you introduce other talloc from NULL context, and if so, fix all of them. If there's a different talloc object from whihc we can allocate the new data, use that. If not, introduce a new context off our tall_bsc_ctx or so, something like a tall_pcomp_ctx, which is then used for all allocations related to compression. https://gerrit.osmocom.org/#/c/642/31/openbsc/src/gprs/gprs_sndcp_pcomp.c File openbsc/src/gprs/gprs_sndcp_pcomp.c: Line 106: data_o = talloc_zero_size(NULL, len); please never use the NULl talloc context. Always use a meaningful context so we can keep track of the allocatiosn. -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 31 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:34:25 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:34:25 +0000 Subject: openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Patch Set 31: Code-Review-1 -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 31 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:37:10 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:37:10 +0000 Subject: osmo-pcu[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:37:18 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:37:18 +0000 Subject: [MERGED] osmo-pcu[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: heed VTY 'line vty'/'bind' command ...................................................................... heed VTY 'line vty'/'bind' command Like most other osmo-* programs, bind the telnet VTY to the address specified by the 'line vty'/'bind' command. This is added by vty_init(), so until now the PCU offered this config but ignored it. Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d --- M src/pcu_main.cpp 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index afdfdc7..4a75c79 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -251,7 +251,8 @@ fprintf(stderr, "No config file: '%s' Using default config.\n", config_file); - rc = telnet_init(tall_pcu_ctx, NULL, OSMO_VTY_PORT_PCU); + rc = telnet_init_dynif(tall_pcu_ctx, NULL, vty_get_bind_addr(), + OSMO_VTY_PORT_PCU); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4cca05a212ec0d493b906014dc3a83e687ebbb1d Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels_test_account From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:37:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:37:52 +0000 Subject: libosmocore[master]: bitrev_test: don't omit last byte from test result check In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/865 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:38:24 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:38:24 +0000 Subject: osmo-bts[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/754 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:38:30 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:38:30 +0000 Subject: [MERGED] osmo-bts[master]: heed VTY 'line vty'/'bind' command In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: heed VTY 'line vty'/'bind' command ...................................................................... heed VTY 'line vty'/'bind' command Like most other osmo-* programs, bind the telnet VTY to the address specified by the 'line vty'/'bind' command. This is added by vty_init(), so until now the BTS offered this config but ignored it. Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d --- M src/common/main.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/main.c b/src/common/main.c index 5e0f1a1..99febe0 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -303,7 +303,8 @@ bts_controlif_setup(bts); - rc = telnet_init(tall_bts_ctx, NULL, g_vty_port_num); + rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(), + g_vty_port_num); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/754 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:39:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:39:02 +0000 Subject: libosmocore[master]: log telnet bind address and port In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/891 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1da7b9076311d9458caea732fc0daace6533a3fd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:39:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:39:06 +0000 Subject: libosmocore[master]: log CTRL bind address and port In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/892 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If449d0514e3d0cc1b346d7452194d931aa090166 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:39:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:39:13 +0000 Subject: [MERGED] libosmocore[master]: log CTRL bind address and port In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log CTRL bind address and port ...................................................................... log CTRL bind address and port Log 'CTRL at 1.2.3.4 5678' from ctrl_interface_setup*. All callers can now drop any extra 'CTRL at 1.2.3.4 5678' logging. Change-Id: If449d0514e3d0cc1b346d7452194d931aa090166 --- M src/ctrl/control_if.c 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 05f6c76..2ffc251 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -669,11 +669,14 @@ if (ret) goto err_vec; + LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; err_vec: vector_free(ctrl_node_vec); ctrl_node_vec = NULL; err: + LOGP(DLCTRL, LOGL_ERROR, "Cannot bind CTRL at %s %u\n", + bind_addr, port); talloc_free(ctrl); return NULL; } -- To view, visit https://gerrit.osmocom.org/892 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If449d0514e3d0cc1b346d7452194d931aa090166 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:39:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:39:13 +0000 Subject: [MERGED] libosmocore[master]: log telnet bind address and port In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log telnet bind address and port ...................................................................... log telnet bind address and port Log 'telnet at 1.2.3.4 5678' from telnet_init*. All callers can now drop any extra 'VTY at 1.2.3.4 5678' logging. Change-Id: I1da7b9076311d9458caea732fc0daace6533a3fd --- M src/vty/telnet_interface.c 1 file changed, 8 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/vty/telnet_interface.c b/src/vty/telnet_interface.c index 50b08c8..e86a6b1 100644 --- a/src/vty/telnet_interface.c +++ b/src/vty/telnet_interface.c @@ -86,7 +86,14 @@ server_socket.data = priv; - return (rc < 0) ? -1 : 0; + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "Cannot bind telnet at %s %d\n", + ip, port); + return -1; + } + + LOGP(DLGLOBAL, LOGL_NOTICE, "telnet at %s %d\n", ip, port); + return 0; } extern struct host host; -- To view, visit https://gerrit.osmocom.org/891 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1da7b9076311d9458caea732fc0daace6533a3fd Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:42:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:42:02 +0000 Subject: libosmocore[master]: msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/847 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:42:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:42:23 +0000 Subject: osmo-bts[master]: sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/848 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:42:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:42:39 +0000 Subject: libosmocore[master]: gprs: Increase NS_ALLOC_SIZE to 3k In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/806 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: daniel Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:42:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:42:46 +0000 Subject: [MERGED] libosmocore[master]: gprs: Increase NS_ALLOC_SIZE to 3k In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gprs: Increase NS_ALLOC_SIZE to 3k ...................................................................... gprs: Increase NS_ALLOC_SIZE to 3k 2k can be insufficient when responding with a STATUS message to a long LLC packet because the original message is included in the STATUS. Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Ticket: SYS#2967 Sponsored-by: On-Waves ehf --- M include/osmocom/gprs/gprs_ns.h 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h index 7c3b23c..130d8c0 100644 --- a/include/osmocom/gprs/gprs_ns.h +++ b/include/osmocom/gprs/gprs_ns.h @@ -23,7 +23,8 @@ "Alive Timer (Tns-alive) timeout\n" \ "Alive Timer (Tns-alive) number of retries\n" -#define NS_ALLOC_SIZE 2048 +/* Educated guess - LLC user payload is 1500 bytes plus possible headers */ +#define NS_ALLOC_SIZE 3072 #define NS_ALLOC_HEADROOM 20 enum ns_timeout { -- To view, visit https://gerrit.osmocom.org/806 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6f76751cfadf61e87ce4367a38907083e1c98562 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: daniel Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 02:43:12 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 23 Sep 2016 02:43:12 +0000 Subject: [MERGED] openbsc[master]: bts: extend bts_chan_load to allow counting tch only In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: bts: extend bts_chan_load to allow counting tch only ...................................................................... bts: extend bts_chan_load to allow counting tch only Change-Id: I86f1d502649747b6b9aefcb39081b14110e8f494 --- M openbsc/include/openbsc/chan_alloc.h M openbsc/src/libbsc/bsc_ctrl_commands.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/chan_alloc.c M openbsc/src/libbsc/paging.c 5 files changed, 30 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h index 78242e5..d919b51 100644 --- a/openbsc/include/openbsc/chan_alloc.h +++ b/openbsc/include/openbsc/chan_alloc.h @@ -46,7 +46,7 @@ struct load_counter pchan[_GSM_PCHAN_MAX]; }; -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts); +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, int only_count_tch); void network_chan_load(struct pchan_load *pl, struct gsm_network *net); int trx_is_usable(struct gsm_bts_trx *trx); diff --git a/openbsc/src/libbsc/bsc_ctrl_commands.c b/openbsc/src/libbsc/bsc_ctrl_commands.c index 7e84797..3f4fee2 100644 --- a/openbsc/src/libbsc/bsc_ctrl_commands.c +++ b/openbsc/src/libbsc/bsc_ctrl_commands.c @@ -239,7 +239,7 @@ bts = cmd->node; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts); + bts_chan_load(&pl, bts, 0); cmd->reply = talloc_strdup(cmd, ""); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 5c95e85..01eec23 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -329,7 +329,7 @@ /* FIXME: chan_desc */ memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts); + bts_chan_load(&pl, bts, 0); vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE); dump_pchan_load_vty(vty, " ", &pl); } diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c index 7b0c3e6..03d44e0 100644 --- a/openbsc/src/libbsc/chan_alloc.c +++ b/openbsc/src/libbsc/chan_alloc.c @@ -514,7 +514,28 @@ return NULL; } -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts) +static int chan_is_tch(struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F: + case GSM_PCHAN_TCH_H: + return 1; + case GSM_PCHAN_TCH_F_PDCH: + case GSM_PCHAN_TCH_F_TCH_H_PDCH: + if (ts->dyn.pchan_is == GSM_PCHAN_TCH_F || + ts->dyn.pchan_is == GSM_PCHAN_TCH_H) + return 1; + else + return 0; + default: + return 0; + } +} + + + +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, + int only_count_tch) { struct gsm_bts_trx *trx; @@ -534,6 +555,9 @@ /* skip administratively deactivated timeslots */ if (!nm_is_running(&ts->mo.nm_state)) + continue; + + if (only_count_tch && !chan_is_tch(ts)) continue; subslots = ts_subslots(ts); @@ -561,6 +585,5 @@ memset(pl, 0, sizeof(*pl)); llist_for_each_entry(bts, &net->bts_list, list) - bts_chan_load(pl, bts); + bts_chan_load(pl, bts, 0); } - diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index fcb4deb..e3795b3 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -119,7 +119,7 @@ int count; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts); + bts_chan_load(&pl, bts, 0); switch (rsl_type) { case RSL_CHANNEED_TCH_F: -- To view, visit https://gerrit.osmocom.org/793 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I86f1d502649747b6b9aefcb39081b14110e8f494 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 07:01:31 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 23 Sep 2016 07:01:31 +0000 Subject: [PATCH] libosmocore[master]: libosmocoding: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/933 to look at the new patch set (#2). libosmocoding: migrate transcoding routines from OsmoBTS There are some projects, such as GR-GSM and OsmocomBB, which would benefit from using one shared implementation of GSM 05.03 code. So, this commit introduces a new sub-library called libosmocoding, which (for now) provides GSM, GPRS and EDGE transcoding routines, migrated from OsmoBTS. The original GSM 05.03 code from OsmoBTS was relicensed under GPLv2-or-later with permission of copyright holders (Andreas Eversberg, Alexander Chemeris and Tom Tsou). The following data types are currently supported: - xCCH - PDTCH (CS 2,3 and MCS 1-9) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 --- A Doxyfile.coding.in M Makefile.am M configure.ac M debian/control M include/Makefile.am A include/osmocom/coding/gsm0503_coding.h A include/osmocom/coding/gsm0503_interleaving.h A include/osmocom/coding/gsm0503_mapping.h A include/osmocom/coding/gsm0503_parity.h A include/osmocom/coding/gsm0503_tables.h A libosmocoding.pc.in A src/coding/Makefile.am A src/coding/gsm0503_coding.c A src/coding/gsm0503_interleaving.c A src/coding/gsm0503_mapping.c A src/coding/gsm0503_parity.c A src/coding/gsm0503_tables.c M src/gsm/libosmogsm.map 18 files changed, 7,505 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/933/2 -- To view, visit https://gerrit.osmocom.org/933 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 07:13:00 2016 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 23 Sep 2016 07:13:00 +0000 Subject: [PATCH] libosmocore[master]: libosmocoding: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/933 to look at the new patch set (#3). libosmocoding: migrate transcoding routines from OsmoBTS There are some projects, such as GR-GSM and OsmocomBB, which would benefit from using one shared implementation of GSM 05.03 code. So, this commit introduces a new sub-library called libosmocoding, which (for now) provides GSM, GPRS and EDGE transcoding routines, migrated from OsmoBTS. The original GSM 05.03 code from OsmoBTS was relicensed under GPLv2-or-later with permission of copyright holders (Andreas Eversberg, Alexander Chemeris and Tom Tsou). The following data types are currently supported: - xCCH - PDTCH (CS 2,3 and MCS 1-9) - TCH/FR - TCH/HR - TCH/AFS - RCH/AHS - RACH - SCH Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 --- M .gitignore A Doxyfile.coding.in M Makefile.am M configure.ac M debian/control M include/Makefile.am A include/osmocom/coding/gsm0503_coding.h A include/osmocom/coding/gsm0503_interleaving.h A include/osmocom/coding/gsm0503_mapping.h A include/osmocom/coding/gsm0503_parity.h A include/osmocom/coding/gsm0503_tables.h A libosmocoding.pc.in A src/coding/Makefile.am A src/coding/gsm0503_coding.c A src/coding/gsm0503_interleaving.c A src/coding/gsm0503_mapping.c A src/coding/gsm0503_parity.c A src/coding/gsm0503_tables.c M src/gsm/libosmogsm.map 19 files changed, 7,512 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/933/3 -- To view, visit https://gerrit.osmocom.org/933 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 11:55:26 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 23 Sep 2016 11:55:26 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/642 to look at the new patch set (#32). SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,474 insertions(+), 31 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/42/642/32 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 12e1a66..e28c507 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,8 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_comp.h \ + gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..4e15b9b --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 22809b7..9537c0a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 06c12d7..c044f24 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -71,6 +71,8 @@ gprs_gmm.c \ gprs_sgsn.c \ gprs_sndcp.c \ + gprs_sndcp_comp.c \ + gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ sgsn_main.c \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index a2ffa51..ff771b8 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -269,9 +291,13 @@ gprs_llc_process_xid_ind(gph->data, gph->data_len, response, sizeof(response), lle); - xid = msgb_put(resp, response_len); - memcpy(xid, response, response_len); - + if (response_len < 0) { + LOGP(DLLC, LOGL_ERROR, + "invalid XID indication received!\n"); + } else { + xid = msgb_put(resp, response_len); + memcpy(xid, response, response_len); + } gprs_llc_tx_xid(lle, resp, 0); } else { LOGP(DLLC, LOGL_NOTICE, @@ -525,11 +551,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..c006d9b 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -76,6 +201,14 @@ }; LLIST_HEAD(gprs_sndcp_entities); + +/* Check if any compression parameters are set in the sgsn configuration */ +static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + return true; + else + return false; +} /* Enqueue a fragment into the defragment queue */ static int defrag_enqueue(struct gprs_sndcp_entity *sne, uint8_t seg_nr, @@ -143,6 +276,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +309,58 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (any_pcomp_or_dcomp_active(sgsn)) + talloc_free(expnd); + + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +521,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +559,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +625,40 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + /* Apply header compression */ + rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + } +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +680,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +700,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +723,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +753,70 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (any_pcomp_or_dcomp_active(sgsn)) + talloc_free(expnd); + + return rc; } #if 0 @@ -619,3 +876,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..5f6fb2c --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,280 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + uint8_t *data_o; + + /* Create a working copy of the incoming data */ + data_o = talloc_zero_size(comp, len); + memcpy(data_o, data, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + memcpy(data, data_o, compr_len); + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + memcpy(data, data_o, compr_len); + } else + *pcomp_index = 0; + + talloc_free(data_o); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 04bd40a..9f65325 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef BUILD_IU #include @@ -317,6 +318,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -324,7 +327,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index bab3f0e..1447577 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -59,6 +59,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 32 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 23 11:55:26 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 23 Sep 2016 11:55:26 +0000 Subject: [PATCH] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/803 to look at the new patch set (#7). SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 585 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/03/803/7 diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 3014d5f..c6a0149 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -26,6 +26,7 @@ gprs_sgsn.h \ gprs_sndcp.h \ gprs_sndcp_comp.h \ + gprs_sndcp_dcomp.h \ gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..a76b4a4 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,53 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 9537c0a..786e2b2 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3970ba6..d228b39 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -72,6 +72,7 @@ gprs_sgsn.c \ gprs_sndcp.c \ gprs_sndcp_comp.c \ + gprs_sndcp_dcomp.c \ gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index c006d9b..0b18f81 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -204,7 +205,8 @@ /* Check if any compression parameters are set in the sgsn configuration */ static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) { - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) return true; else return false; @@ -324,11 +326,22 @@ #endif if (any_pcomp_or_dcomp_active(sgsn)) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -653,6 +666,19 @@ * the new, compressed buffer size */ msgb_get(msg, msg->len); msgb_put(msg, rc); + + /* Apply data compression */ + rc = gprs_sndcp_dcomp_compress(msg->data, msg->len, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); } #if DEBUG_IP_PACKETS == 1 DEBUGP(DSNDCP, "===================================================\n"); @@ -784,11 +810,22 @@ #endif if (any_pcomp_or_dcomp_active(sgsn)) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -884,8 +921,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -901,6 +941,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -1008,13 +1065,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->v42bis_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..489106b --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,357 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void v42bis_reset(v42bis_state_t *comp) +{ + /* This function performs a complete reset of the V.42bis compression + * state by reinitalizing the state withe the previously negotiated + * parameters. */ + + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + uint8_t *data_o; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Run compressor */ + data_o = talloc_zero_size(comp, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_o; + compressed_data.buf_pointer = data_o; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + talloc_free(data_o); + return len; + } + + *pcomp_index = 1; + memcpy(data, data_o, compressed_data.len); + talloc_free(data_o); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int v42bis_expand_unitdata(uint8_t *data, unsigned int len, + uint8_t pcomp_index, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + int rc; + struct v42bis_output_buffer uncompressed_data; + uint8_t *data_i; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Decompress packet */ + data_i = talloc_zero_size(comp, len); + memcpy(data_i, data, len); + uncompressed_data.buf = data; + uncompressed_data.buf_pointer = data; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + talloc_free(data_i); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = v42bis_expand_unitdata(data, len, pcomp_index, comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = v42bis_compress_unitdata(&pcomp_index, data, len, + comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 9f3260d..fb5b6d5 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -299,6 +299,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 9250632..9ee5455 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -62,6 +62,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 23 14:53:46 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 23 Sep 2016 14:53:46 +0000 Subject: [MERGED] osmo-bts[master]: DTX: fix last SID saving In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: DTX: fix last SID saving ...................................................................... DTX: fix last SID saving Previously SID was saved explicitly by each BTS model (lc15, sysmo) instead of relying on generic function. Fix it by using generic function and propagating necessary parameters for it. Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Fixes: OS#1800 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 14 insertions(+), 26 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 3672b8f..da63e00 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 2d136af..41d6989 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -88,7 +88,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 187f688..5badc4d 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,7 +200,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -270,14 +270,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } @@ -297,7 +291,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; uint8_t *l1_payload; @@ -329,7 +323,7 @@ case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + rtp_pl_len, lchan, fn); break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 40ac12d..787a91d 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,7 @@ l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len); + msg->data, msg->len, u32Fn); } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 2fc8a29..bd694ec 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -108,7 +108,7 @@ /* tch.c */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 39feae1..6c78ceb 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,7 +283,7 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan) + struct gsm_lchan *lchan, uint32_t fn) { struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; enum osmo_amr_type ft; @@ -367,14 +367,8 @@ } #endif - if (ft == AMR_SID) { - /* store the last SID frame in lchan context */ - unsigned int copy_len; - copy_len = OSMO_MIN(payload_len+1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); - } + if (ft == AMR_SID) + save_last_sid(lchan, l1_payload, payload_len, fn, sti); return payload_len+1; } @@ -394,7 +388,7 @@ * pre-fill the primtive. */ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; uint8_t *l1_payload; @@ -428,7 +422,7 @@ case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan); + rtp_pl_len, lchan, fn); break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/845 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 23 15:00:18 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 23 Sep 2016 15:00:18 +0000 Subject: [MERGED] osmo-bts[master]: DTX: fix SID repeat scheduling In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: DTX: fix SID repeat scheduling ...................................................................... DTX: fix SID repeat scheduling Previously SID retransmission was scheduled incorrectly based on GSM frames instead of voice frames. Fix this by using GSM Fn only as elapsed time estimation: * move saved SID retransmission into generic function from lc15 and sysmo specific code * split retransmission time check into separate generic function * compute estimation for elapsed time since last retransmission using GSM Fn Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Fixes: OS#1799 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 66 insertions(+), 116 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 591d194..cde7a93 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -23,6 +23,8 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, uint32_t fn, bool update); +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f12c653..967b10d 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -111,6 +112,49 @@ memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type) or 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + return 0; +} + +/*! \brief Check if enough time has passed since last SID (if any) to repeat it + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +{ + /* Compute approx. time delta based on Fn duration */ + uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.last_sid.fn); + + /* according to 3GPP TS 26.093 A.5.1.1: */ + if (lchan->tch.last_sid.is_update) { + /* SID UPDATE should be repeated every 8th RTP frame */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 8) + return true; + return false; + } + /* 3rd frame after SID FIRST should be SID UPDATE */ + if (delta < GSM_RTP_FRAME_DURATION_MS * 3) + return true; + return false; +} + static inline bool fn_chk(const uint8_t *t, uint32_t fn) { uint8_t i; diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5badc4d..4fdf6a6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -463,27 +463,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -506,30 +485,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -541,14 +503,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -556,14 +513,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 6c78ceb..ee72e53 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -566,27 +566,6 @@ return -EINVAL; } -static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) -{ - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *l1_payload; - - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - l1_payload = &msu_param->u8Buffer[1]; - - if (lchan->tch.last_sid.len) { - memcpy(l1_payload, lchan->tch.last_sid.buf, - lchan->tch.last_sid.len); - msu_param->u8Size = lchan->tch.last_sid.len + 1; - return true; - } - return false; -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; @@ -609,30 +588,13 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - /* according to 3GPP TS 26.093 A.5.1.1: */ - if (lchan->tch.last_sid.is_update) { - /* SID UPDATE should be repeated every 8th frame */ - if (fn - lchan->tch.last_sid.fn < 7) { - msgb_free(msg); - return NULL; - } - } else { - /* 3rd frame after SID FIRST should be SID UPDATE */ - if (fn - lchan->tch.last_sid.fn < 3) { - msgb_free(msg); - return NULL; - } + if (dtx_amr_sid_optional(lchan, fn)) { + msgb_free(msg); + return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH " - "(FN=%u) but SID buffer is empty - sent NO_DATA\n", - fn); - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, - AMR_GOOD); - return msg; - } + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) + osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) @@ -644,14 +606,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; @@ -659,14 +616,9 @@ msgb_free(msg); return NULL; } - if (repeat_last_sid(lchan, msg)) - return msg; - else { - LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH " - "(FN=%u) but SID buffer is empty - sent nothing\n", - fn); + msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); + if (!msu_param->u8Size) return NULL; - } break; default: msgb_free(msg); -- To view, visit https://gerrit.osmocom.org/857 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 23 15:06:09 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 23 Sep 2016 15:06:09 +0000 Subject: [MERGED] osmo-bts[master]: DTX: fix SID logic In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: DTX: fix SID logic ...................................................................... DTX: fix SID logic Previously receiving SID via RTP always caused it's transmission to L1 regardless of the time which might have resulted in excess traffic. Fix this by only saving SID data and transmitting it later on as necessary according to 3GPP TS 26.093 A.5.1.1. Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Fixes: OS#1801 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 38 insertions(+), 18 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index da63e00..21d047a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -466,10 +466,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (!l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn)) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 41d6989..f01fdc2 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -87,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 4fdf6a6..6ac2763 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -270,8 +270,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -279,9 +281,9 @@ #define RTP_MSGB_ALLOC_SIZE 512 /*! \brief function for incoming RTP via TCH.req - * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -290,7 +292,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; @@ -324,6 +326,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; break; default: /* we don't support CSD modes */ @@ -334,13 +338,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return; + return false; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); + return true; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 787a91d..41b09a1 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -459,10 +459,13 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - l1if_tch_encode(lchan, - l1p->u.phDataReq.msgUnitParam.u8Buffer, - &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn); + if (!l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn)) { + msgb_free(nmsg); + nmsg = NULL; + } } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index bd694ec..49b7e67 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -11,6 +11,8 @@ #include +#include + enum { MQ_SYS_READ, MQ_L1_READ, @@ -107,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index ee72e53..4ea95c5 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -367,8 +367,10 @@ } #endif - if (ft == AMR_SID) + if (ft == AMR_SID) { save_last_sid(lchan, l1_payload, payload_len, fn, sti); + return -EALREADY; + } return payload_len+1; } @@ -376,9 +378,9 @@ #define RTP_MSGB_ALLOC_SIZE 512 /*! \brief function for incoming RTP via TCH.req - * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -387,7 +389,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) { uint8_t *payload_type; @@ -423,6 +425,8 @@ *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; break; default: /* we don't support CSD modes */ @@ -433,13 +437,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return; + return false; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); + return true; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/858 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 23 15:16:16 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 23 Sep 2016 15:16:16 +0000 Subject: [MERGED] osmo-bts[master]: lc15, sysmo: Use SID_FIRST_P1 to initiate DTX In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: lc15, sysmo: Use SID_FIRST_P1 to initiate DTX ...................................................................... lc15, sysmo: Use SID_FIRST_P1 to initiate DTX Some phone seems to not send SID_FIRST_P2 message which seems like a different understanding of the DTX spec. L1 accommodates for that by using P1 to supply data for SID. Hence we should use it to initiate DTX and ignore P2 message in case of AMR HR. Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 2 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 6ac2763..3c6ee25 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -445,8 +445,7 @@ case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; - case GsmL1_TchPlType_Amr_SidFirstP2: - /* L1 do not give us SID_FIRST data, just indication */ + case GsmL1_TchPlType_Amr_SidFirstP1: memcpy(sid_first, payload, payload_len); int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); if (len < 0) diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 4ea95c5..745923c 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -548,8 +548,7 @@ case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; - case GsmL1_TchPlType_Amr_SidFirstP2: - /* L1 do not give us SID_FIRST data, just indication */ + case GsmL1_TchPlType_Amr_SidFirstP1: memcpy(sid_first, payload, payload_len); int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); if (len < 0) -- To view, visit https://gerrit.osmocom.org/692 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 23 15:27:44 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 23 Sep 2016 15:27:44 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#10). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M include/osmo-bts/msg_utils.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 9 files changed, 82 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/10 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index cde7a93..f03eb43 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -10,6 +10,9 @@ struct msgb; +/* Access 1st byte of msgb control buffer */ +#define rtpmsg_marker_bit(x) ((x)->cb[0]) + /** * Classification of OML message. ETSI for plain GSM 12.21 * messages and IPA/Osmo for manufacturer messages. diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..042cc7e 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -659,7 +659,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +691,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = rtpmsg_marker_bit(resp_msg); + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +705,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1054,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1067,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + rtpmsg_marker_bit(msg) = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 21d047a..0779dac 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -503,7 +504,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index f01fdc2..88d71bf 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -90,7 +90,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 6ac2763..cbe7edc 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -283,6 +286,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -293,10 +297,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -323,11 +330,21 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 41b09a1..3c6db43 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -496,6 +497,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 49b7e67..a90c39b 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 4ea95c5..2d86fca 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -380,6 +383,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -390,10 +394,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -422,11 +429,21 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 10 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:16:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:16:01 +0000 Subject: openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Patch Set 32: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 32 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:17:50 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:17:50 +0000 Subject: openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:17:59 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:17:59 +0000 Subject: [MERGED] openbsc[master]: SNDCP: add V.42bis data compression functionality In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SNDCP: add V.42bis data compression functionality ...................................................................... SNDCP: add V.42bis data compression functionality - Add compression control for V.42bis Add code to handle compression (gprs_sndcp_dcomp.c/h) - Add Adjustments in SNDCP - Add VTY commands Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e --- M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_dcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_dcomp.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 10 files changed, 585 insertions(+), 18 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 3014d5f..c6a0149 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -26,6 +26,7 @@ gprs_sgsn.h \ gprs_sndcp.h \ gprs_sndcp_comp.h \ + gprs_sndcp_dcomp.h \ gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ diff --git a/openbsc/include/openbsc/gprs_sndcp_dcomp.h b/openbsc/include/openbsc/gprs_sndcp_dcomp.h new file mode 100644 index 0000000..a76b4a4 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_dcomp.h @@ -0,0 +1,53 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 9537c0a..786e2b2 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -100,6 +100,15 @@ int passive; int s01; } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3970ba6..d228b39 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -72,6 +72,7 @@ gprs_sgsn.c \ gprs_sndcp.c \ gprs_sndcp_comp.c \ + gprs_sndcp_dcomp.c \ gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index c006d9b..0b18f81 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ @@ -204,7 +205,8 @@ /* Check if any compression parameters are set in the sgsn configuration */ static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) { - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || + sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) return true; else return false; @@ -324,11 +326,22 @@ #endif if (any_pcomp_or_dcomp_active(sgsn)) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -653,6 +666,19 @@ * the new, compressed buffer size */ msgb_get(msg, msg->len); msgb_put(msg, rc); + + /* Apply data compression */ + rc = gprs_sndcp_dcomp_compress(msg->data, msg->len, &dcomp, + lle->llme->comp.data, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); } #if DEBUG_IP_PACKETS == 1 DEBUGP(DSNDCP, "===================================================\n"); @@ -784,11 +810,22 @@ #endif if (any_pcomp_or_dcomp_active(sgsn)) { - expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + + MAX_HDRDECOMPR_INCR); memcpy(expnd, npdu, npdu_len); + /* Apply data decompression */ + rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, + sne->defrag.data); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, sne->defrag.proto); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, @@ -884,8 +921,11 @@ LLIST_HEAD(comp_fields); struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); /* Setup rfc1144 */ if (sgsn->cfg.pcomp_rfc1144.active) { @@ -901,6 +941,23 @@ rfc1144_comp_field.rfc1144_params = &rfc1144_params; entity++; llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Setup V.42bis */ + if (sgsn->cfg.dcomp_v42bis.active) { + v42bis_params.nsapi[0] = nsapi; + v42bis_params.nsapi_len = 1; + v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; + v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; + v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = entity; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + entity++; + llist_add(&v42bis_comp_field.list, &comp_fields); } /* Compile bytestream */ @@ -1008,13 +1065,19 @@ /* Process proposed parameters */ switch (comp_field->algo) { case V42BIS: - /* V42BIS is not yet supported, - * so we set applicable nsapis to zero */ - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - comp_field->v42bis_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); + if (sgsn->cfg.dcomp_v42bis.passive && + comp_field->v42bis_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting V.42bis data compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, + comp_field); + } else { + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + comp_field->v42bis_params->nsapi_len = 0; + } break; case V44: /* V44 is not yet supported, diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index 1a9d030..b13cb8b 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -34,6 +34,7 @@ #include #include #include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, @@ -100,16 +101,16 @@ comp_entity = NULL; } } else { - LOGP(DSNDCP, LOGL_ERROR, - "We don't support data compression yet!\n"); - talloc_free(comp_entity); - return NULL; + if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } } /* Display info message */ if (comp_entity == NULL) { LOGP(DSNDCP, LOGL_ERROR, - "Header compression entity (%d) creation failed!\n", + "Compression entity (%d) creation failed!\n", comp_entity->entity); return NULL; } @@ -159,6 +160,7 @@ LOGP(DSNDCP, LOGL_INFO, "Deleting data compression entity %d ...\n", comp_entity->entity); + gprs_sndcp_dcomp_term(comp_entity); } } diff --git a/openbsc/src/gprs/gprs_sndcp_dcomp.c b/openbsc/src/gprs/gprs_sndcp_dcomp.c new file mode 100644 index 0000000..489106b --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_dcomp.c @@ -0,0 +1,357 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A struct to capture the output data of compressor and decompressor */ +struct v42bis_output_buffer { + uint8_t *buf; + uint8_t *buf_pointer; + int len; +}; + +/* Handler to capture the output data from the compressor */ +void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, pkt, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Handler to capture the output data from the decompressor */ +void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) +{ + struct v42bis_output_buffer *output_buffer = + (struct v42bis_output_buffer *)user_data; + memcpy(output_buffer->buf_pointer, buf, len); + output_buffer->buf_pointer += len; + output_buffer->len += len; + return; +} + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new data compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + comp_entity->state = + v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, + comp_field->v42bis_params->p1, + comp_field->v42bis_params->p2, + &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, + &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a data compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION + && comp_entity->algo == V42BIS) { + if (comp_entity->state) { + v42bis_free((v42bis_state_t *) comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "V.42bis data compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Perform a full reset of the V.42bis compression state */ +static void v42bis_reset(v42bis_state_t *comp) +{ + /* This function performs a complete reset of the V.42bis compression + * state by reinitalizing the state withe the previously negotiated + * parameters. */ + + int p0, p1, p2; + p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; + p1 = comp->decompress.v42bis_parm_n2; + p2 = comp->decompress.v42bis_parm_n7; + + DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", + comp, p0, p1, p2); + + v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, + V42BIS_MAX_OUTPUT_LENGTH); +} + +/* Compress a packet using V.42bis data compression */ +static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + uint8_t *data_o; + int rc; + int skip = 0; + struct v42bis_output_buffer compressed_data; + + /* Don't bother with short packets */ + if (len < MIN_COMPR_PAYLOAD) + skip = 1; + + /* Skip if compression is not enabled for TX direction */ + if (!comp->compress.v42bis_parm_p0) + skip = 1; + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Run compressor */ + data_o = talloc_zero_size(comp, len * MAX_DATADECOMPR_FAC); + compressed_data.buf = data_o; + compressed_data.buf_pointer = data_o; + compressed_data.len = 0; + comp->compress.user_data = (&compressed_data); + rc = v42bis_compress(comp, data, len); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + rc = v42bis_compress_flush(comp); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression failed, skipping...\n"); + skip = 1; + } + + /* The compressor might yield negative compression gain, in + * this case, we just decide to send the packat as normal, + * uncompressed payload => skip compresssion */ + if (compressed_data.len >= len) { + LOGP(DSNDCP, LOGL_ERROR, + "Data compression ineffective, skipping...\n"); + skip = 1; + } + + /* Skip compression */ + if (skip) { + *pcomp_index = 0; + talloc_free(data_o); + return len; + } + + *pcomp_index = 1; + memcpy(data, data_o, compressed_data.len); + talloc_free(data_o); + + return compressed_data.len; +} + +/* Expand a packet using V.42bis data compression */ +static int v42bis_expand_unitdata(uint8_t *data, unsigned int len, + uint8_t pcomp_index, v42bis_state_t *comp) +{ + /* Note: This implementation may only be used to compress SN_UNITDATA + * packets, since it resets the compression state for each NPDU. */ + + int rc; + struct v42bis_output_buffer uncompressed_data; + uint8_t *data_i; + + /* Skip when the packet is marked as uncompressed */ + if (pcomp_index == 0) { + return len; + } + + /* Reset V.42bis compression state */ + v42bis_reset(comp); + + /* Decompress packet */ + data_i = talloc_zero_size(comp, len); + memcpy(data_i, data, len); + uncompressed_data.buf = data; + uncompressed_data.buf_pointer = data; + uncompressed_data.len = 0; + comp->decompress.user_data = (&uncompressed_data); + rc = v42bis_decompress(comp, data_i, len); + talloc_free(data_i); + if (rc < 0) + return -EINVAL; + rc = v42bis_decompress_flush(comp); + if (rc < 0) + return -EINVAL; + + return uncompressed_data.len; +} + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = v42bis_expand_unitdata(data, len, pcomp_index, comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression entity list: comp_entities=%p\n", comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only data compression entities may appear in + * data compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); + + /* Note: Currently V42BIS is the only compression method we + * support, so the only allowed algorithm is V42BIS */ + OSMO_ASSERT(comp_entity->algo == V42BIS); + + /* Run compression algo */ + rc = v42bis_compress_unitdata(&pcomp_index, data, len, + comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Data compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 9f3260d..fb5b6d5 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -299,6 +299,11 @@ .description = "RFC1144 TCP/IP Header compression (SLHC)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DV42BIS] = { + .name = "DV42BIS", + .description = "V.42bis data compression (SNDCP)", + .enabled = 1, .loglevel = LOGL_DEBUG, + } }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 0eea350..1b477e5 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -277,6 +277,26 @@ } else vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { + vty_out(vty, + " compression v42bis active direction sgsn codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { + vty_out(vty, + " compression v42bis active direction ms codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { + vty_out(vty, + " compression v42bis active direction both codewords %d strlen %d%s", + g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, + VTY_NEWLINE); + } else if (g_cfg->dcomp_v42bis.passive) { + vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1117,6 +1137,59 @@ return CMD_SUCCESS; } +DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, + "no compression v42bis", + NO_STR COMPRESSION_STR "disable V.42bis data compression\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, + "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is actively proposed\n" + "Direction in which the compression shall be active (p0)\n" + "Compress ms->sgsn direction only\n" + "Compress sgsn->ms direction only\n" + "Both directions\n" + "Number of codewords (p1)\n" + "Number of codewords\n" + "Maximum string length (p2)\n" "Maximum string length\n") +{ + g_cfg->dcomp_v42bis.active = 1; + g_cfg->dcomp_v42bis.passive = 1; + + switch (argv[0][0]) { + case 'm': + g_cfg->dcomp_v42bis.p0 = 1; + break; + case 's': + g_cfg->dcomp_v42bis.p0 = 2; + break; + case 'b': + g_cfg->dcomp_v42bis.p0 = 3; + break; + } + + g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); + g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, + "compression v42bis passive", + COMPRESSION_STR + "V.42bis data compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->dcomp_v42bis.active = 0; + g_cfg->dcomp_v42bis.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1174,7 +1247,9 @@ install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - + install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); + install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index 9250632..9ee5455 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -62,6 +62,7 @@ $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/gprs/v42bis.o \ + $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/803 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6d36cbdf2f5c5f83ca9ba57c70452f02b8582e7e Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:17:59 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:17:59 +0000 Subject: [MERGED] openbsc[master]: SNDCP: add RFC1144 header compression functionality In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SNDCP: add RFC1144 header compression functionality ...................................................................... SNDCP: add RFC1144 header compression functionality - Add module to handle compression entities - Add module to control header compression - Introduce VTY commands for heade compression configuration - Add changes in sndcp and llc to integrate header compression Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 --- M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/gprs_llc.h M openbsc/include/openbsc/gprs_sndcp.h A openbsc/include/openbsc/gprs_sndcp_comp.h A openbsc/include/openbsc/gprs_sndcp_pcomp.h M openbsc/include/openbsc/sgsn.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c A openbsc/src/gprs/gprs_sndcp_comp.c A openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/gprs/sgsn_vty.c M openbsc/tests/sgsn/Makefile.am 14 files changed, 1,474 insertions(+), 31 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 12e1a66..e28c507 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,8 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_comp.h \ + gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index c3b82b1..8b01467 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -174,6 +174,15 @@ * able to create the compression entity. */ struct llist_head *xid; + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + /* Internal management */ uint32_t age_timestamp; }; diff --git a/openbsc/include/openbsc/gprs_sndcp.h b/openbsc/include/openbsc/gprs_sndcp.h index fef871a..d970240 100644 --- a/openbsc/include/openbsc/gprs_sndcp.h +++ b/openbsc/include/openbsc/gprs_sndcp.h @@ -21,6 +21,16 @@ struct llist_head frag_list; struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; }; /* See 6.7.1.2 Reassembly */ @@ -50,4 +60,20 @@ extern struct llist_head gprs_sndcp_entities; +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + #endif /* INT_SNDCP_H */ diff --git a/openbsc/include/openbsc/gprs_sndcp_comp.h b/openbsc/include/openbsc/gprs_sndcp_comp.h new file mode 100644 index 0000000..87ab638 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/openbsc/include/openbsc/gprs_sndcp_pcomp.h b/openbsc/include/openbsc/gprs_sndcp_pcomp.h new file mode 100644 index 0000000..4e15b9b --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index 22809b7..9537c0a 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -93,6 +93,13 @@ int dynamic_lookup; struct oap_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; }; struct sgsn_instance { diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 06c12d7..c044f24 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -71,6 +71,8 @@ gprs_gmm.c \ gprs_sgsn.c \ gprs_sndcp.c \ + gprs_sndcp_comp.c \ + gprs_sndcp_pcomp.c \ gprs_sndcp_vty.c \ gprs_sndcp_xid.c \ sgsn_main.c \ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index a2ffa51..ff771b8 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); @@ -140,6 +141,16 @@ struct llist_head *xid_fields; struct gprs_llc_xid_field *xid_field; + struct gprs_llc_xid_field *xid_field_request; + struct gprs_llc_xid_field *xid_field_request_l3 = NULL; + + /* Pick layer3 XID from the XID request we have sent last */ + if (lle->llme->xid) { + llist_for_each_entry(xid_field_request, lle->llme->xid, list) { + if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) + xid_field_request_l3 = xid_field_request; + } + } /* Parse and analyze XID-Response */ xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); @@ -150,12 +161,10 @@ llist_for_each_entry(xid_field, xid_fields, list) { /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - LOGP(DLLC, LOGL_NOTICE, - "Ignoring SNDCP-XID-Field: XID: type=%i, data_len=%i, data=%s\n", - xid_field->type, xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && + xid_field_request_l3) { + sndcp_sn_xid_conf(xid_field, + xid_field_request_l3, lle); } /* Process LLC-XID fields: */ @@ -204,10 +213,6 @@ struct gprs_llc_xid_field *xid_field; struct gprs_llc_xid_field *xid_field_response; - /* Flush eventually pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - /* Parse and analyze XID-Request */ xid_fields = gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); @@ -236,6 +241,23 @@ (lle->llme, xid_field); llist_add(&xid_field_response->list, xid_fields_response); + } + } + + /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ + llist_for_each_entry(xid_field, xid_fields, list) { + if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { + + xid_field_response = + talloc_zero(lle->llme, + struct gprs_llc_xid_field); + rc = sndcp_sn_xid_ind(xid_field, + xid_field_response, lle); + if (rc == 0) + llist_add(&xid_field_response->list, + xid_fields_response); + else + talloc_free(xid_field_response); } } @@ -269,9 +291,13 @@ gprs_llc_process_xid_ind(gph->data, gph->data_len, response, sizeof(response), lle); - xid = msgb_put(resp, response_len); - memcpy(xid, response, response_len); - + if (response_len < 0) { + LOGP(DLLC, LOGL_ERROR, + "invalid XID indication received!\n"); + } else { + xid = msgb_put(resp, response_len); + memcpy(xid, response, response_len); + } gprs_llc_tx_xid(lle, resp, 0); } else { LOGP(DLLC, LOGL_NOTICE, @@ -525,11 +551,16 @@ llist_add(&llme->list, &gprs_llc_llmes); + llme->comp.proto = gprs_sndcp_comp_alloc(llme); + llme->comp.data = gprs_sndcp_comp_alloc(llme); + return llme; } static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_comp_free(llme->comp.proto); + gprs_sndcp_comp_free(llme->comp.data); talloc_free(llme->xid); llist_del(&llme->list); talloc_free(llme); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 4f71121..c006d9b 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -35,6 +35,131 @@ #include #include #include +#include +#include +#include +#include + +#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ + +#if DEBUG_IP_PACKETS == 1 +/* Calculate TCP/IP checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Show some ip packet details */ +static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) +{ + uint8_t tcp_flags; + char flags_debugmsg[256]; + int len_short; + static unsigned int packet_count = 0; + static unsigned int tcp_csum_err_count = 0; + static unsigned int ip_csum_err_count = 0; + + packet_count++; + + if (len > 80) + len_short = 80; + else + len_short = len; + + if (dir) + DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + else + DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, + osmo_hexdump_nospc(data, len_short)); + + DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); + DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); + + if (len < 20) { + DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); + return; + } + + if (calc_ip_csum(data, 20) != 0) { + DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); + ip_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); + + if (data[9] == 0x06) { + if (len < 40) { + DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); + return; + } + + DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); + tcp_flags = data[33]; + + if (calc_tcpip_csum(NULL, data, len) != 0) { + DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); + tcp_csum_err_count++; + } else + DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); + + memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); + if (tcp_flags & 1) + strcat(flags_debugmsg, "FIN "); + if (tcp_flags & 2) + strcat(flags_debugmsg, "SYN "); + if (tcp_flags & 4) + strcat(flags_debugmsg, "RST "); + if (tcp_flags & 8) + strcat(flags_debugmsg, "PSH "); + if (tcp_flags & 16) + strcat(flags_debugmsg, "ACK "); + if (tcp_flags & 32) + strcat(flags_debugmsg, "URG "); + DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); + } else if (data[9] == 0x11) { + DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); + } else { + DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); + } + + DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, + ip_csum_err_count); + DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, + tcp_csum_err_count); +} +#endif /* Chapter 7.2: SN-PDU Formats */ struct sndcp_common_hdr { @@ -76,6 +201,14 @@ }; LLIST_HEAD(gprs_sndcp_entities); + +/* Check if any compression parameters are set in the sgsn configuration */ +static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) { + if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive) + return true; + else + return false; +} /* Enqueue a fragment into the defragment queue */ static int defrag_enqueue(struct gprs_sndcp_entity *sne, uint8_t seg_nr, @@ -143,6 +276,9 @@ struct msgb *msg; unsigned int seg_nr; uint8_t *npdu; + int npdu_len; + int rc; + uint8_t *expnd = NULL; LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, @@ -173,16 +309,58 @@ talloc_free(dqe); } + npdu_len = sne->defrag.tot_len; + /* FIXME: cancel timer */ /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, sne->defrag.tot_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (any_pcomp_or_dcomp_active(sgsn)) + talloc_free(expnd); + + return rc; } -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr, - unsigned int len) +static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, + uint8_t *hdr, unsigned int len) { struct sndcp_common_hdr *sch; struct sndcp_udata_hdr *suh; @@ -343,7 +521,8 @@ }; /* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs) +static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, + uint8_t pcomp, uint8_t dcomp) { struct gprs_sndcp_entity *sne = fs->sne; struct gprs_llc_lle *lle = sne->lle; @@ -380,8 +559,8 @@ if (sch->first) { scomph = (struct sndcp_comp_hdr *) msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; } /* append the user-data header */ @@ -446,8 +625,40 @@ struct sndcp_comp_hdr *scomph; struct sndcp_udata_hdr *suh; struct sndcp_frag_state fs; + uint8_t pcomp = 0; + uint8_t dcomp = 0; + int rc; /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ + + /* Compress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); + debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + /* Apply header compression */ + rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, + lle->llme->comp.proto, nsapi); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header compression failed!\n"); + return -EIO; + } + + /* Fixup pointer locations and sizes in message buffer to match + * the new, compressed buffer size */ + msgb_get(msg, msg->len); + msgb_put(msg, rc); + } +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif sne = gprs_sndcp_entity_by_lle(lle, nsapi); if (!sne) { @@ -469,7 +680,7 @@ /* call function to generate and send fragments until all * of the N-PDU has been sent */ while (1) { - int rc = sndcp_send_ud_frag(&fs); + int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); if (rc == 0) return 0; if (rc < 0) @@ -489,8 +700,8 @@ sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = 0; - scomph->dcomp = 0; + scomph->pcomp = pcomp; + scomph->dcomp = dcomp; /* prepend common SNDCP header */ sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); @@ -512,6 +723,8 @@ uint8_t *npdu; uint16_t npdu_num __attribute__((unused)); int npdu_len; + int rc; + uint8_t *expnd = NULL; sch = (struct sndcp_common_hdr *) hdr; if (sch->first) { @@ -540,26 +753,70 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); + if(scomph) { + sne->defrag.pcomp = scomph->pcomp; + sne->defrag.dcomp = scomph->dcomp; + sne->defrag.proto = lle->llme->comp.proto; + sne->defrag.data = lle->llme->comp.data; + } + /* any non-first segment is by definition something to defragment * as is any segment that tells us there are more segments */ if (!sch->first || sch->more) return defrag_input(sne, msg, hdr, len); - if (scomph && (scomph->pcomp || scomph->dcomp)) { - LOGP(DSNDCP, LOGL_ERROR, "We don't support compression yet\n"); - return -EIO; - } - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu; + npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ + if (npdu_len <= 0) { LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); return -EIO; } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + + /* Decompress packet */ +#if DEBUG_IP_PACKETS == 1 + DEBUGP(DSNDCP, " \n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, "===================================================\n"); +#endif + if (any_pcomp_or_dcomp_active(sgsn)) { + + expnd = talloc_zero_size(msg, npdu_len + MAX_HDRDECOMPR_INCR); + memcpy(expnd, npdu, npdu_len); + + /* Apply header decompression */ + rc = gprs_sndcp_pcomp_expand(expnd, npdu_len, sne->defrag.pcomp, + sne->defrag.proto); + if (rc < 0) { + LOGP(DSNDCP, LOGL_ERROR, + "TCP/IP Header decompression failed!\n"); + talloc_free(expnd); + return -EIO; + } + + /* Modify npu length, expnd is handed directly handed + * over to gsn_rx_sndcp_ud_ind(), see below */ + npdu_len = rc; + } else + expnd = npdu; +#if DEBUG_IP_PACKETS == 1 + debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); + DEBUGP(DSNDCP, "===================================================\n"); + DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); + DEBUGP(DSNDCP, " \n"); +#endif + + /* Hand off packet to gtp */ + rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, + sne->nsapi, msg, npdu_len, expnd); + + if (any_pcomp_or_dcomp_active(sgsn)) + talloc_free(expnd); + + return rc; } #if 0 @@ -619,3 +876,322 @@ case LL_STATUS_IND: } #endif + +/* Generate SNDCP-XID message */ +static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) +{ + int entity = 0; + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup rfc1144 */ + if (sgsn->cfg.pcomp_rfc1144.active) { + rfc1144_params.nsapi[0] = nsapi; + rfc1144_params.nsapi_len = 1; + rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = entity; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + entity++; + llist_add(&rfc1144_comp_field.list, &comp_fields); + } + + /* Compile bytestream */ + return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields); +} + +/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) +{ + /* Note: The specification requires the SNDCP-User to set of an + * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter + * negotiation, Figure 11: SNDCP XID negotiation procedure. In + * our case the SNDCP-User is sgsn_libgtp.c, which calls + * sndcp_sn_xid_req directly. */ + + uint8_t l3params[1024]; + int xid_len; + struct gprs_llc_xid_field xid_field_request; + + /* Wipe off all compression entities and their states to + * get rid of possible leftovers from a previous session */ + gprs_sndcp_comp_free(lle->llme->comp.proto); + gprs_sndcp_comp_free(lle->llme->comp.data); + lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); + lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); + talloc_free(lle->llme->xid); + lle->llme->xid = NULL; + + /* Generate compression parameter bytestream */ + xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); + + /* Send XID with the SNDCP-XID bytetsream included */ + if (xid_len > 0) { + xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; + xid_field_request.data = l3params; + xid_field_request.data_len = xid_len; + return gprs_ll_xid_req(lle, &xid_field_request); + } + + /* When bytestream can not be generated, proceed without SNDCP-XID */ + return gprs_ll_xid_req(lle, NULL); + +} + +/* Handle header compression entites */ +static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* Note: This functions also transforms the comp_field into its + * echo form (strips comp values, resets propose bit etc...) + * the processed comp_fields can then be sent back as XID- + * Response without further modification. */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case RFC_1144: + if (sgsn->cfg.pcomp_rfc1144.passive + && comp_field->rfc1144_params->nsapi_len > 0) { + DEBUGP(DSNDCP, + "Accepting RFC1144 header compression...\n"); + gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, + comp_field); + } else { + DEBUGP(DSNDCP, + "Rejecting RFC1144 header compression...\n"); + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + comp_field->rfc1144_params->nsapi_len = 0; + } + break; + case RFC_2507: + /* RFC 2507 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); + comp_field->rfc2507_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + case ROHC: + /* ROHC is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); + comp_field->rohc_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + break; + } + + return 0; +} + +/* Hanle data compression entites */ +static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, + struct gprs_llc_lle *lle) +{ + /* See note in handle_pcomp_entities() */ + + /* Delete propose bit */ + comp_field->p = 0; + + /* Process proposed parameters */ + switch (comp_field->algo) { + case V42BIS: + /* V42BIS is not yet supported, + * so we set applicable nsapis to zero */ + LOGP(DSNDCP, LOGL_DEBUG, + "Rejecting V.42bis data compression...\n"); + comp_field->v42bis_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + case V44: + /* V44 is not yet supported, + * so we set applicable nsapis to zero */ + DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); + comp_field->v44_params->nsapi_len = 0; + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + break; + } + + return 0; + +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle) +{ + /* Note: This function computes the SNDCP-XID response that is sent + * back to the ms when a ms originated XID is received. The + * Input XID fields are directly processed and the result is directly + * handed back. */ + + int rc; + int compclass; + + struct llist_head *comp_fields; + struct gprs_sndcp_comp_field *comp_field; + + OSMO_ASSERT(xid_field_indication); + OSMO_ASSERT(xid_field_response); + OSMO_ASSERT(lle); + + /* Parse SNDCP-CID XID-Field */ + comp_fields = gprs_sndcp_parse_xid(lle->llme, + xid_field_indication->data, + xid_field_indication->data_len, + NULL); + if (!comp_fields) + return -EINVAL; + + /* Don't bother with empty indications */ + if (llist_empty(comp_fields)) { + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + DEBUGP(DSNDCP, + "SNDCP-XID indication did not contain any parameters!\n"); + return 0; + } + + /* Handle compression entites */ + DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + llist_for_each_entry(comp_field, comp_fields, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } + } + + DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); + + /* Reserve some memory to store the modified SNDCP-XID bytes */ + xid_field_response->data = + talloc_zero_size(lle->llme, xid_field_indication->data_len); + + /* Set Type flag for response */ + xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; + + /* Compile modified SNDCP-XID bytes */ + rc = gprs_sndcp_compile_xid(xid_field_response->data, + xid_field_indication->data_len, + comp_fields); + + if (rc > 0) + xid_field_response->data_len = rc; + else { + talloc_free(xid_field_response->data); + xid_field_response->data = NULL; + xid_field_response->data_len = 0; + return -EINVAL; + } + + talloc_free(comp_fields); + + return 0; +} + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle) +{ + /* Note: This function handles an incomming SNDCP-XID confirmiation. + * Since the confirmation fields may lack important parameters we + * will reconstruct these missing fields using the original request + * we have sent. After that we will create (or delete) the + * compression entites */ + + struct llist_head *comp_fields_req; + struct llist_head *comp_fields_conf; + struct gprs_sndcp_comp_field *comp_field; + int rc; + int compclass; + + /* We need both, the confirmation that is sent back by the ms, + * and the original request we have sent. If one of this is missing + * we can not process the confirmation, the caller must check if + * request and confirmation fields are available. */ + OSMO_ASSERT(xid_field_conf); + OSMO_ASSERT(xid_field_request); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_req = gprs_sndcp_parse_xid(lle->llme, + xid_field_request->data, + xid_field_request->data_len, + NULL); + if (!comp_fields_req) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); + + /* Parse SNDCP-CID XID-Field */ + comp_fields_conf = gprs_sndcp_parse_xid(lle->llme, + xid_field_conf->data, + xid_field_conf->data_len, + comp_fields_req); + if (!comp_fields_conf) + return -EINVAL; + + DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); + gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); + + /* Handle compression entites */ + llist_for_each_entry(comp_field, comp_fields_conf, list) { + compclass = gprs_sndcp_get_compression_class(comp_field); + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = handle_pcomp_entities(comp_field, lle); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = handle_dcomp_entities(comp_field, lle); + else { + gprs_sndcp_comp_delete(lle->llme->comp.proto, + comp_field->entity); + gprs_sndcp_comp_delete(lle->llme->comp.data, + comp_field->entity); + rc = 0; + } + + if (rc < 0) { + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + return -EINVAL; + } + } + + talloc_free(comp_fields_req); + talloc_free(comp_fields_conf); + + return 0; +} diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c new file mode 100644 index 0000000..1a9d030 --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -0,0 +1,320 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Create a new compression entity from a XID-Field */ +static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, + const struct + gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); + + /* Copy relevant information from the SNDCP-XID field */ + comp_entity->entity = comp_field->entity; + comp_entity->comp_len = comp_field->comp_len; + memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); + + if (comp_field->rfc1144_params) { + comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc1144_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rfc2507_params) { + comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->rfc2507_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->rohc_params) { + comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; + memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v42bis_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else if (comp_field->v44_params) { + comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + memcpy(comp_entity->nsapi, + comp_field->v42bis_params->nsapi, + sizeof(comp_entity->nsapi)); + } else { + /* The caller is expected to check carefully if the all + * data fields required for compression entity creation + * are present. Otherwise we blow an assertion here */ + OSMO_ASSERT(false); + } + comp_entity->algo = comp_field->algo; + + /* Check if an NSAPI is selected, if not, it does not make sense + * to create the compression entity, since the caller should + * have checked the presence of the NSAPI, we blow an assertion + * in case of missing NSAPIs */ + OSMO_ASSERT(comp_entity->nsapi_len > 0); + + /* Determine of which class our compression entity will be + * (Protocol or Data compresson ?) */ + comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); + + OSMO_ASSERT(comp_entity->compclass != -1); + + /* Create an algorithm specific compression context */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { + talloc_free(comp_entity); + comp_entity = NULL; + } + } else { + LOGP(DSNDCP, LOGL_ERROR, + "We don't support data compression yet!\n"); + talloc_free(comp_entity); + return NULL; + } + + /* Display info message */ + if (comp_entity == NULL) { + LOGP(DSNDCP, LOGL_ERROR, + "Header compression entity (%d) creation failed!\n", + comp_entity->entity); + return NULL; + } + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "New header compression entity (%d) created.\n", + comp_entity->entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "New data compression entity (%d) created.\n", + comp_entity->entity); + } + + return comp_entity; +} + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) +{ + struct llist_head *lh; + + lh = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(lh); + + return lh; +} + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities) +{ + struct gprs_sndcp_comp *comp_entity; + + /* We expect the caller to take care of allocating a + * compression entity list properly. Attempting to + * free a non existing list clearly points out + * a malfunction. */ + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + /* Free compression entity */ + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity->entity); + gprs_sndcp_pcomp_term(comp_entity); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity->entity); + } + } + + talloc_free(comp_entities); +} + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, + unsigned int entity) +{ + struct gprs_sndcp_comp *comp_entity; + struct gprs_sndcp_comp *comp_entity_to_delete = NULL; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + if (comp_entity->entity == entity) { + comp_entity_to_delete = comp_entity; + break; + } + } + + if (!comp_entity_to_delete) + return; + + if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + LOGP(DSNDCP, LOGL_INFO, + "Deleting header compression entity %d ...\n", + comp_entity_to_delete->entity); + gprs_sndcp_pcomp_term(comp_entity_to_delete); + } else { + LOGP(DSNDCP, LOGL_INFO, + "Deleting data compression entity %d ...\n", + comp_entity_to_delete->entity); + } + + /* Delete compression entity */ + llist_del(&comp_entity_to_delete->list); + talloc_free(comp_entity_to_delete); +} + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field) +{ + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(comp_entities); + OSMO_ASSERT(comp_field); + + /* Just to be sure, if the entity is already in + * the list it will be deleted now */ + gprs_sndcp_comp_delete(comp_entities, comp_field->entity); + + /* Create and add a new entity to the list */ + comp_entity = gprs_sndcp_comp_create(ctx, comp_field); + + if (!comp_entity) + return NULL; + + llist_add(&comp_entity->list, comp_entities); + return comp_entity; +} + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return comp_entity; + } + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", + comp); + return NULL; +} + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi) +{ + struct gprs_sndcp_comp *comp_entity; + int i; + + OSMO_ASSERT(comp_entities); + + llist_for_each_entry(comp_entity, comp_entities, list) { + for (i = 0; i < comp_entity->nsapi_len; i++) { + if (comp_entity->nsapi[i] == nsapi) + return comp_entity; + } + } + + return NULL; +} + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp) +{ + /* Note: This function returns a normalized version of the comp value, + * which matches up with the position of the comp field. Since comp=0 + * is reserved for "no compression", the index value starts counting + * at one. The return value is the PCOMPn/DCOMPn value one can find + * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ + + int i; + OSMO_ASSERT(comp_entity); + + /* A pcomp/dcomp value of zero is reserved for "no comproession", + * So we just bail and return zero in this case */ + if (comp == 0) + return 0; + + /* Look in the pcomp/dcomp list for the index */ + for (i = 0; i < comp_entity->comp_len; i++) { + if (comp_entity->comp[i] == comp) + return i + 1; + } + + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching comp_index for given pcomp/dcomp value %d\n", + comp); + return 0; +} + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index) +{ + OSMO_ASSERT(comp_entity); + + /* A comp_index of zero translates to zero right away. */ + if (comp_index == 0) + return 0; + + if (comp_index > comp_entity->comp_len) { + LOGP(DSNDCP, LOGL_ERROR, + "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", + comp_index); + return 0; + } + + /* Look in the pcomp/dcomp list for the comp_index, see + * note in gprs_sndcp_comp_get_idx() */ + return comp_entity->comp[comp_index - 1]; +} diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c new file mode 100644 index 0000000..5f6fb2c --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -0,0 +1,280 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a new header compression + * entity is created by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + OSMO_ASSERT(comp_field); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + comp_entity->state = + slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, + comp_field->rfc1144_params->s01 + 1); + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression initalized.\n"); + return 0; + } + + /* Just in case someone tries to initalize an unknown or unsupported + * header compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) +{ + /* Note: This function is automatically called from + * gprs_sndcp_comp.c when a header compression + * entity is deleted by gprs_sndcp.c */ + + OSMO_ASSERT(comp_entity); + + if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION + && comp_entity->algo == RFC_1144) { + if (comp_entity->state) { + slhc_free((struct slcompress *)comp_entity->state); + comp_entity->state = NULL; + } + LOGP(DSNDCP, LOGL_INFO, + "RFC1144 header compression terminated.\n"); + return; + } + + /* Just in case someone tries to terminate an unknown or unsupported + * data compresson. Since everything is checked during the SNDCP + * negotiation process, this should never happen! */ + OSMO_ASSERT(false); +} + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, + unsigned int len, struct slcompress *comp) +{ + uint8_t *comp_ptr; + int compr_len; + uint8_t *data_o; + + /* Create a working copy of the incoming data */ + data_o = talloc_zero_size(comp, len); + memcpy(data_o, data, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); + + /* Generate pcomp_index */ + if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + *pcomp_index = 2; + data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; + memcpy(data, data_o, compr_len); + } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == + SL_TYPE_UNCOMPRESSED_TCP) { + *pcomp_index = 1; + data_o[0] &= 0x4F; + memcpy(data, data_o, compr_len); + } else + *pcomp_index = 0; + + talloc_free(data_o); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, + struct slcompress *comp) +{ + int data_decompressed_len; + int type; + + /* Note: this function should never be called with pcomp_index=0, + * since this condition is already filtered + * out by gprs_sndcp_pcomp_expand() */ + + /* Determine the data type by the PCOMP index */ + switch (pcomp_index) { + case 0: + type = SL_TYPE_IP; + case 1: + type = SL_TYPE_UNCOMPRESSED_TCP; + break; + case 2: + type = SL_TYPE_COMPRESSED_TCP; + break; + default: + LOGP(DSNDCP, LOGL_ERROR, + "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", + pcomp_index); + type = SL_TYPE_IP; + break; + } + + /* Restore the original version nibble on + * marked uncompressed packets */ + if (type == SL_TYPE_UNCOMPRESSED_TCP) { + /* Just in case the phone tags uncompressed tcp-data + * (normally this is handled by pcomp so there is + * no need for tagging the data) */ + data[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (type == SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); + + /* Skip on pcomp=0 */ + if (pcomp == 0) { + return len; + } + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Find pcomp_index */ + pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); + + /* Run decompression algo */ + rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header expansion done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + + return rc; +} + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi) +{ + int rc; + uint8_t pcomp_index = 0; + struct gprs_sndcp_comp *comp_entity; + + OSMO_ASSERT(data); + OSMO_ASSERT(pcomp); + OSMO_ASSERT(comp_entities); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression entity list: comp_entities=%p\n", + comp_entities); + + /* Find out which compression entity handles the data */ + comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); + + /* Skip compression if no suitable compression entity can be found */ + if (!comp_entity) { + *pcomp = 0; + return len; + } + + /* Note: Only protocol compression entities may appear in + * protocol compression context */ + OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); + + /* Note: Currently RFC1144 is the only compression method we + * support, so the only allowed algorithm is RFC1144 */ + OSMO_ASSERT(comp_entity->algo == RFC_1144); + + /* Run compression algo */ + rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); + slhc_i_status(comp_entity->state); + slhc_o_status(comp_entity->state); + + /* Find pcomp value */ + *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); + + LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); + + LOGP(DSNDCP, LOGL_DEBUG, + "Header compression done, old length=%d, new length=%d, entity=%p\n", + len, rc, comp_entity); + return rc; +} diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 04bd40a..9f65325 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef BUILD_IU #include @@ -317,6 +318,8 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) { struct sgsn_signal_data sig_data; + int rc; + struct gprs_llc_lle *lle; /* Inform others about it */ memset(&sig_data, 0, sizeof(sig_data)); @@ -324,7 +327,17 @@ osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); /* Send PDP CTX ACT to MS */ - return gsm48_tx_gsm_act_pdp_acc(pctx); + rc = gsm48_tx_gsm_act_pdp_acc(pctx); + if(rc < 0) + return rc; + + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if(rc < 0) + return rc; + + return 0; } /* The GGSN has confirmed the creation of a PDP Context */ diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index e6dc68d..0eea350 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -269,6 +269,14 @@ vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); + if (g_cfg->pcomp_rfc1144.active) { + vty_out(vty, " compression rfc1144 active slots %d%s", + g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); + } else if (g_cfg->pcomp_rfc1144.passive) { + vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); + } else + vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -1074,6 +1082,41 @@ return CMD_SUCCESS; } +#define COMPRESSION_STR "Configure compression\n" +DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, + "no compression rfc1144", + NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 0; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, + "compression rfc1144 active slots <1-256>", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is actively proposed\n" + "Number of compression state slots\n" + "Number of compression state slots\n") +{ + g_cfg->pcomp_rfc1144.active = 1; + g_cfg->pcomp_rfc1144.passive = 1; + g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, + "compression rfc1144 passive", + COMPRESSION_STR + "RFC1144 Header compresion scheme\n" + "Compression is available on request\n") +{ + g_cfg->pcomp_rfc1144.active = 0; + g_cfg->pcomp_rfc1144.passive = 1; + return CMD_SUCCESS; +} + int sgsn_vty_init(void) { install_element_ve(&show_sgsn_cmd); @@ -1128,6 +1171,10 @@ install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); + install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); + install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); + return 0; } diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index bab3f0e..1447577 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -59,6 +59,8 @@ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ + $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ -- To view, visit https://gerrit.osmocom.org/642 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia00260dc09978844c2865957b4d43000b78b5e43 Gerrit-PatchSet: 33 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:17:59 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:17:59 +0000 Subject: [MERGED] openbsc[master]: V.42bis: integration and unit test In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: V.42bis: integration and unit test ...................................................................... V.42bis: integration and unit test - Edit previously committed V.42bis implementation to function outside IAXmodem. - Add unit test to verify the correct function of V.42bis Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h M openbsc/include/openbsc/v42bis.h M openbsc/include/openbsc/v42bis_private.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/v42bis.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am M openbsc/tests/testsuite.at A openbsc/tests/v42bis/Makefile.am A openbsc/tests/v42bis/v42bis_test.c A openbsc/tests/v42bis/v42bis_test.ok 14 files changed, 1,135 insertions(+), 15 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified -- To view, visit https://gerrit.osmocom.org/644 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I689413f2541b6def0625ce6bd96f1f488f05f99d Gerrit-PatchSet: 41 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:18:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:18:00 +0000 Subject: [MERGED] openbsc[master]: V.42bis: add sourcecode from IAXmodem (SPANDSP) In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: V.42bis: add sourcecode from IAXmodem (SPANDSP) ...................................................................... V.42bis: add sourcecode from IAXmodem (SPANDSP) V.42bis is a data compression method found in modems. It has also been specified for GPRS as data compression algorithm. The implementation has been taken from IAXmodem: https://sourceforge.net/p/iaxmodem/code/HEAD/tree/ svn checkout svn://svn.code.sf.net/p/iaxmodem/code/ iaxmodem-code Revision: r36 Change-Id: Iabedece9f97ca944a1e3f747bb073e532c4e9dca --- A openbsc/include/openbsc/v42bis.h A openbsc/include/openbsc/v42bis_private.h A openbsc/src/gprs/v42bis.c 3 files changed, 1,031 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/v42bis.h b/openbsc/include/openbsc/v42bis.h new file mode 100644 index 0000000..b947a61 --- /dev/null +++ b/openbsc/include/openbsc/v42bis.h @@ -0,0 +1,140 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005, 2011 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \page v42bis_page V.42bis modem data compression +\section v42bis_page_sec_1 What does it do? +The v.42bis specification defines a data compression scheme, to work in +conjunction with the error correction scheme defined in V.42. + +\section v42bis_page_sec_2 How does it work? +*/ + +#if !defined(_SPANDSP_V42BIS_H_) +#define _SPANDSP_V42BIS_H_ + +#define V42BIS_MIN_STRING_SIZE 6 +#define V42BIS_MAX_STRING_SIZE 250 +#define V42BIS_MIN_DICTIONARY_SIZE 512 +#define V42BIS_MAX_BITS 12 +#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ +#define V42BIS_MAX_OUTPUT_LENGTH 1024 + +enum +{ + V42BIS_P0_NEITHER_DIRECTION = 0, + V42BIS_P0_INITIATOR_RESPONDER, + V42BIS_P0_RESPONDER_INITIATOR, + V42BIS_P0_BOTH_DIRECTIONS +}; + +enum +{ + V42BIS_COMPRESSION_MODE_DYNAMIC = 0, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER +}; + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +typedef struct v42bis_state_s v42bis_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Compress a block of octets. + \param s The V.42bis context. + \param buf The data to be compressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in a compression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s); + +/*! Decompress a block of octets. + \param s The V.42bis context. + \param buf The data to be decompressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in the decompression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *s); + +/*! Set the compression mode. + \param s The V.42bis context. + \param mode One of the V.42bis compression modes - + V42BIS_COMPRESSION_MODE_DYNAMIC, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER */ +SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode); + +/*! Initialise a V.42bis context. + \param s The V.42bis context. + \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. + \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. + \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. + \param encode_handler Encode callback handler. + \param encode_user_data An opaque pointer passed to the encode callback handler. + \param max_encode_len The maximum length that should be passed to the encode handler. + \param decode_handler Decode callback handler. + \param decode_user_data An opaque pointer passed to the decode callback handler. + \param max_decode_len The maximum length that should be passed to the decode handler. + \return The V.42bis context. */ +SPAN_DECLARE(v42bis_state_t *) v42bis_init(v42bis_state_t *s, + int negotiated_p0, + int negotiated_p1, + int negotiated_p2, + put_msg_func_t encode_handler, + void *encode_user_data, + int max_encode_len, + put_msg_func_t decode_handler, + void *decode_user_data, + int max_decode_len); + +/*! Release a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s); + +/*! Free a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/openbsc/include/openbsc/v42bis_private.h b/openbsc/include/openbsc/v42bis_private.h new file mode 100644 index 0000000..2c801eb --- /dev/null +++ b/openbsc/include/openbsc/v42bis_private.h @@ -0,0 +1,127 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * private/v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(_SPANDSP_PRIVATE_V42BIS_H_) +#define _SPANDSP_PRIVATE_V42BIS_H_ + +/*! + V.42bis dictionary node. + Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used + as a "no such value" marker in this structure. +*/ +typedef struct +{ + /*! \brief The value of the octet represented by the current dictionary node */ + uint8_t node_octet; + /*! \brief The parent of this node */ + uint16_t parent; + /*! \brief The first child of this node */ + uint16_t child; + /*! \brief The next node at the same depth */ + uint16_t next; +} v42bis_dict_node_t; + +/*! + V.42bis compression or decompression. This defines the working state for a single instance + of V.42bis compression or decompression. +*/ +typedef struct +{ + /*! \brief Compression enabled. */ + int v42bis_parm_p0; + /*! \brief Compression mode. */ + int compression_mode; + /*! \brief Callback function to handle output data. */ + put_msg_func_t handler; + /*! \brief An opaque pointer passed in calls to the data handler. */ + void *user_data; + /*! \brief The maximum amount to be passed to the data handler. */ + int max_output_len; + + /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ + int transparent; + /*! \brief Next empty dictionary entry */ + uint16_t v42bis_parm_c1; + /*! \brief Current codeword size */ + uint16_t v42bis_parm_c2; + /*! \brief Threshold for codeword size change */ + uint16_t v42bis_parm_c3; + /*! \brief The current update point in the dictionary */ + uint16_t update_at; + /*! \brief The last entry matched in the dictionary */ + uint16_t last_matched; + /*! \brief The last entry added to the dictionary */ + uint16_t last_added; + /*! \brief Total number of codewords in the dictionary */ + int v42bis_parm_n2; + /*! \brief Maximum permitted string length */ + int v42bis_parm_n7; + /*! \brief The dictionary */ + v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; + + /*! \brief The octet string in progress */ + uint8_t string[V42BIS_MAX_STRING_SIZE]; + /*! \brief The current length of the octet string in progress */ + int string_length; + /*! \brief The amount of the octet string in progress which has already + been flushed out of the buffer */ + int flushed_length; + + /*! \brief Compression performance metric */ + uint16_t compression_performance; + + /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */ + uint32_t bit_buffer; + /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */ + int bit_count; + + /*! \brief The output composition buffer */ + uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH]; + /*! \brief The length of the contents of the output composition buffer */ + int output_octet_count; + + /*! \brief The current value of the escape code */ + uint8_t escape_code; + /*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */ + int escaped; +} v42bis_comp_state_t; + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +struct v42bis_state_s +{ + /*! \brief Compression state. */ + v42bis_comp_state_t compress; + /*! \brief Decompression state. */ + v42bis_comp_state_t decompress; + + /*! \brief Error and flow logging control */ + logging_state_t logging; +}; + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/openbsc/src/gprs/v42bis.c b/openbsc/src/gprs/v42bis.c new file mode 100644 index 0000000..d025ea9 --- /dev/null +++ b/openbsc/src/gprs/v42bis.c @@ -0,0 +1,764 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * v42bis.c + * + * Written by Steve Underwood + * + * Copyright (C) 2005, 2011 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. + Currently it performs the core compression and decompression functions OK. + However, a number of the bells and whistles in V.42bis are incomplete. */ + +/*! \file */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spandsp/telephony.h" +#include "spandsp/logging.h" +#include "spandsp/bit_operations.h" +#include "spandsp/async.h" +#include "spandsp/v42bis.h" + +#include "spandsp/private/logging.h" +#include "spandsp/private/v42bis.h" + +/* Fixed parameters from the spec. */ +/* Character size (bits) */ +#define V42BIS_N3 8 +/* Number of characters in the alphabet */ +#define V42BIS_N4 256 +/* Index number of first dictionary entry used to store a string */ +#define V42BIS_N5 (V42BIS_N4 + V42BIS_N6) +/* Number of control codewords */ +#define V42BIS_N6 3 +/* V.42bis/9.2 */ +#define V42BIS_ESC_STEP 51 + +/* Compreeibility monitoring parameters for assessing automated switches between + transparent and compressed mode */ +#define COMPRESSIBILITY_MONITOR (256*V42BIS_N3) +#define COMPRESSIBILITY_MONITOR_HYSTERESIS 11 + +/* Control code words in compressed mode */ +enum +{ + V42BIS_ETM = 0, /* Enter transparent mode */ + V42BIS_FLUSH = 1, /* Flush data */ + V42BIS_STEPUP = 2 /* Step up codeword size */ +}; + +/* Command codes in transparent mode */ +enum +{ + V42BIS_ECM = 0, /* Enter compression mode */ + V42BIS_EID = 1, /* Escape character in data */ + V42BIS_RESET = 2 /* Force reinitialisation */ +}; + +static __inline__ void push_octet(v42bis_comp_state_t *s, int octet) +{ + s->output_buf[s->output_octet_count++] = (uint8_t) octet; + if (s->output_octet_count >= s->max_output_len) + { + s->handler(s->user_data, s->output_buf, s->output_octet_count); + s->output_octet_count = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_octets(v42bis_comp_state_t *s, const uint8_t buf[], int len) +{ + int i; + int chunk; + + i = 0; + while ((s->output_octet_count + len - i) >= s->max_output_len) + { + chunk = s->max_output_len - s->output_octet_count; + memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); + s->handler(s->user_data, s->output_buf, s->max_output_len); + s->output_octet_count = 0; + i += chunk; + } + chunk = len - i; + if (chunk > 0) + { + memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); + s->output_octet_count += chunk; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_compressed_code(v42bis_comp_state_t *s, int code) +{ + s->bit_buffer |= code << s->bit_count; + s->bit_count += s->v42bis_parm_c2; + while (s->bit_count >= 8) + { + push_octet(s, s->bit_buffer & 0xFF); + s->bit_buffer >>= 8; + s->bit_count -= 8; + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void push_octet_alignment(v42bis_comp_state_t *s) +{ + if ((s->bit_count & 7)) + { + s->bit_count += (8 - (s->bit_count & 7)); + while (s->bit_count >= 8) + { + push_octet(s, s->bit_buffer & 0xFF); + s->bit_buffer >>= 8; + s->bit_count -= 8; + } + } +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void flush_octets(v42bis_comp_state_t *s) +{ + if (s->output_octet_count > 0) + { + s->handler(s->user_data, s->output_buf, s->output_octet_count); + s->output_octet_count = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +static void dictionary_init(v42bis_comp_state_t *s) +{ + int i; + + memset(s->dict, 0, sizeof(s->dict)); + for (i = 0; i < V42BIS_N4; i++) + s->dict[i + V42BIS_N6].node_octet = i; + s->v42bis_parm_c1 = V42BIS_N5; + s->v42bis_parm_c2 = V42BIS_N3 + 1; + s->v42bis_parm_c3 = V42BIS_N4 << 1; + s->last_matched = 0; + s->update_at = 0; + s->last_added = 0; + s->bit_buffer = 0; + s->bit_count = 0; + s->flushed_length = 0; + s->string_length = 0; + s->escape_code = 0; + s->transparent = TRUE; + s->escaped = FALSE; + s->compression_performance = COMPRESSIBILITY_MONITOR; +} +/*- End of function --------------------------------------------------------*/ + +static uint16_t match_octet(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) +{ + uint16_t e; + + if (at == 0) + return octet + V42BIS_N6; + e = s->dict[at].child; + while (e) + { + if (s->dict[e].node_octet == octet) + return e; + e = s->dict[e].next; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static uint16_t add_octet_to_dictionary(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) +{ + uint16_t newx; + uint16_t next; + uint16_t e; + + newx = s->v42bis_parm_c1; + s->dict[newx].node_octet = octet; + s->dict[newx].parent = at; + s->dict[newx].child = 0; + s->dict[newx].next = s->dict[at].child; + s->dict[at].child = newx; + next = newx; + /* 6.5 Recovering a dictionary entry to use next */ + do + { + /* 6.5(a) and (b) */ + if (++next == s->v42bis_parm_n2) + next = V42BIS_N5; + } + while (s->dict[next].child); + /* 6.5(c) We need to reuse a leaf node */ + if (s->dict[next].parent) + { + /* 6.5(d) Detach the leaf node from its parent, and re-use it */ + e = s->dict[next].parent; + if (s->dict[e].child == next) + { + s->dict[e].child = s->dict[next].next; + } + else + { + e = s->dict[e].child; + while (s->dict[e].next != next) + e = s->dict[e].next; + s->dict[e].next = s->dict[next].next; + } + } + s->v42bis_parm_c1 = next; + return newx; +} +/*- End of function --------------------------------------------------------*/ + +static void send_string(v42bis_comp_state_t *s) +{ + push_octets(s, s->string, s->string_length); + s->string_length = 0; + s->flushed_length = 0; +} +/*- End of function --------------------------------------------------------*/ + +static void expand_codeword_to_string(v42bis_comp_state_t *s, uint16_t code) +{ + int i; + uint16_t p; + + /* Work out the length */ + for (i = 0, p = code; p; i++) + p = s->dict[p].parent; + s->string_length += i; + /* Now expand the known length of string */ + i = s->string_length - 1; + for (p = code; p; ) + { + s->string[i--] = s->dict[p].node_octet; + p = s->dict[p].parent; + } +} +/*- End of function --------------------------------------------------------*/ + +static void send_encoded_data(v42bis_comp_state_t *s, uint16_t code) +{ + int i; + + /* Update compressibility metric */ + /* Integrate at the compressed bit rate, and leak at the pre-compression bit rate */ + s->compression_performance += (s->v42bis_parm_c2 - s->compression_performance*s->string_length*V42BIS_N3/COMPRESSIBILITY_MONITOR); + if (s->transparent) + { + for (i = 0; i < s->string_length; i++) + { + push_octet(s, s->string[i]); + if (s->string[i] == s->escape_code) + { + push_octet(s, V42BIS_EID); + s->escape_code += V42BIS_ESC_STEP; + } + } + } + else + { + /* Allow for any escape octets in the string */ + for (i = 0; i < s->string_length; i++) + { + if (s->string[i] == s->escape_code) + s->escape_code += V42BIS_ESC_STEP; + } + /* 7.4 Encoding - we now have the longest matchable string, and will need to output the code for it. */ + while (code >= s->v42bis_parm_c3) + { + /* We need to increase the codeword size */ + /* 7.4(a) */ + push_compressed_code(s, V42BIS_STEPUP); + /* 7.4(b) */ + s->v42bis_parm_c2++; + /* 7.4(c) */ + s->v42bis_parm_c3 <<= 1; + /* 7.4(d) this might need to be repeated, so we loop */ + } + /* 7.5 Transfer - output the last state of the string */ + push_compressed_code(s, code); + } + s->string_length = 0; + s->flushed_length = 0; +} +/*- End of function --------------------------------------------------------*/ + +static void go_compressed(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + if (!s->transparent) + return; + span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to compressed mode\n"); + /* Switch out of transparent now, between codes. We need to send the octet which did not + match, just before switching. */ + if (s->last_matched) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + } + push_octet(s, s->escape_code); + push_octet(s, V42BIS_ECM); + s->bit_buffer = 0; + s->transparent = FALSE; +} +/*- End of function --------------------------------------------------------*/ + +static void go_transparent(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + if (s->transparent) + return; + span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to transparent mode\n"); + /* Switch into transparent now, between codes, and the unmatched octet should + go out in transparent mode, just below */ + if (s->last_matched) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + } + s->last_added = 0; + push_compressed_code(s, V42BIS_ETM); + push_octet_alignment(s); + s->transparent = TRUE; +} +/*- End of function --------------------------------------------------------*/ + +static void monitor_for_mode_change(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + + s = &ss->compress; + switch (s->compression_mode) + { + case V42BIS_COMPRESSION_MODE_DYNAMIC: + /* 7.8 Data compressibility test */ + if (s->transparent) + { + if (s->compression_performance < COMPRESSIBILITY_MONITOR - COMPRESSIBILITY_MONITOR_HYSTERESIS) + { + /* 7.8.1 Transition to compressed mode */ + go_compressed(ss); + } + } + else + { + if (s->compression_performance > COMPRESSIBILITY_MONITOR) + { + /* 7.8.2 Transition to transparent mode */ + go_transparent(ss); + } + } + /* 7.8.3 Reset function - TODO */ + break; + case V42BIS_COMPRESSION_MODE_ALWAYS: + if (s->transparent) + go_compressed(ss); + break; + case V42BIS_COMPRESSION_MODE_NEVER: + if (!s->transparent) + go_transparent(ss); + break; + } +} +/*- End of function --------------------------------------------------------*/ + +static int v42bis_comp_init(v42bis_comp_state_t *s, + int p1, + int p2, + put_msg_func_t handler, + void *user_data, + int max_output_len) +{ + memset(s, 0, sizeof(*s)); + s->v42bis_parm_n2 = p1; + s->v42bis_parm_n7 = p2; + s->handler = handler; + s->user_data = user_data; + s->max_output_len = (max_output_len < V42BIS_MAX_OUTPUT_LENGTH) ? max_output_len : V42BIS_MAX_OUTPUT_LENGTH; + s->output_octet_count = 0; + dictionary_init(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int comp_exit(v42bis_comp_state_t *s) +{ + s->v42bis_parm_n2 = 0; + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *ss, const uint8_t buf[], int len) +{ + v42bis_comp_state_t *s; + int i; + uint16_t code; + + s = &ss->compress; + if (!s->v42bis_parm_p0) + { + /* Compression is off - just push the incoming data out */ + push_octets(s, buf, len); + return 0; + } + for (i = 0; i < len; ) + { + /* 6.4 Add the string to the dictionary */ + if (s->update_at) + { + if (match_octet(s, s->update_at, buf[i]) == 0) + s->last_added = add_octet_to_dictionary(s, s->update_at, buf[i]); + s->update_at = 0; + } + /* Match string */ + while (i < len) + { + code = match_octet(s, s->last_matched, buf[i]); + if (code == 0) + { + s->update_at = s->last_matched; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + if (code == s->last_added) + { + s->last_added = 0; + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + s->last_matched = code; + /* 6.3(b) If the string matches a dictionary entry, and the entry is not that entry + created by the last invocation of the string matching procedure, then the + next character shall be read and appended to the string and this step + repeated. */ + s->string[s->string_length++] = buf[i++]; + /* 6.4(a) The string must not exceed N7 in length */ + if (s->string_length + s->flushed_length == s->v42bis_parm_n7) + { + send_encoded_data(s, s->last_matched); + s->last_matched = 0; + break; + } + } + monitor_for_mode_change(ss); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + int len; + + s = &ss->compress; + if (s->update_at) + return 0; + if (s->last_matched) + { + len = s->string_length; + send_encoded_data(s, s->last_matched); + s->flushed_length += len; + } + if (!s->transparent) + { + s->update_at = s->last_matched; + s->last_matched = 0; + s->flushed_length = 0; + push_compressed_code(s, V42BIS_FLUSH); + push_octet_alignment(s); + } + flush_octets(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *ss, const uint8_t buf[], int len) +{ + v42bis_comp_state_t *s; + int i; + int j; + int yyy; + uint16_t code; + uint16_t p; + uint8_t ch; + uint8_t in; + + s = &ss->decompress; + if (!s->v42bis_parm_p0) + { + /* Compression is off - just push the incoming data out */ + push_octets(s, buf, len); + return 0; + } + for (i = 0; i < len; ) + { + if (s->transparent) + { + in = buf[i]; + if (s->escaped) + { + /* Command */ + s->escaped = FALSE; + switch (in) + { + case V42BIS_ECM: + /* Enter compressed mode */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ECM\n"); + send_string(s); + s->transparent = FALSE; + s->update_at = s->last_matched; + s->last_matched = 0; + i++; + continue; + case V42BIS_EID: + /* Escape symbol */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_EID\n"); + in = s->escape_code; + s->escape_code += V42BIS_ESC_STEP; + break; + case V42BIS_RESET: + /* Reset dictionary */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_RESET\n"); + /* TODO: */ + send_string(s); + dictionary_init(s); + i++; + continue; + default: + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_???? - %" PRIu32 "\n", in); + return -1; + } + } + else if (in == s->escape_code) + { + s->escaped = TRUE; + i++; + continue; + } + + yyy = TRUE; + for (j = 0; j < 2 && yyy; j++) + { + if (s->update_at) + { + if (match_octet(s, s->update_at, in) == 0) + s->last_added = add_octet_to_dictionary(s, s->update_at, in); + s->update_at = 0; + } + + code = match_octet(s, s->last_matched, in); + if (code == 0) + { + s->update_at = s->last_matched; + send_string(s); + s->last_matched = 0; + } + else if (code == s->last_added) + { + s->last_added = 0; + send_string(s); + s->last_matched = 0; + } + else + { + s->last_matched = code; + s->string[s->string_length++] = in; + if (s->string_length + s->flushed_length == s->v42bis_parm_n7) + { + send_string(s); + s->last_matched = 0; + } + i++; + yyy = FALSE; + } + } + } + else + { + /* Get code from input */ + while (s->bit_count < s->v42bis_parm_c2 && i < len) + { + s->bit_buffer |= buf[i++] << s->bit_count; + s->bit_count += 8; + } + if (s->bit_count < s->v42bis_parm_c2) + continue; + code = s->bit_buffer & ((1 << s->v42bis_parm_c2) - 1); + s->bit_buffer >>= s->v42bis_parm_c2; + s->bit_count -= s->v42bis_parm_c2; + + if (code < V42BIS_N6) + { + /* We have a control code. */ + switch (code) + { + case V42BIS_ETM: + /* Enter transparent mode */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ETM\n"); + s->bit_count = 0; + s->transparent = TRUE; + s->last_matched = 0; + s->last_added = 0; + break; + case V42BIS_FLUSH: + /* Flush signal */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_FLUSH\n"); + s->bit_count = 0; + break; + case V42BIS_STEPUP: + /* Increase code word size */ + span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_STEPUP\n"); + s->v42bis_parm_c2++; + s->v42bis_parm_c3 <<= 1; + if (s->v42bis_parm_c2 > (s->v42bis_parm_n2 >> 3)) + return -1; + break; + } + continue; + } + /* Regular codeword */ + if (code == s->v42bis_parm_c1) + return -1; + expand_codeword_to_string(s, code); + if (s->update_at) + { + ch = s->string[0]; + if ((p = match_octet(s, s->update_at, ch)) == 0) + { + s->last_added = add_octet_to_dictionary(s, s->update_at, ch); + if (code == s->v42bis_parm_c1) + return -1; + } + else if (p == s->last_added) + { + s->last_added = 0; + } + } + s->update_at = ((s->string_length + s->flushed_length) == s->v42bis_parm_n7) ? 0 : code; + /* Allow for any escapes which may be in this string */ + for (j = 0; j < s->string_length; j++) + { + if (s->string[j] == s->escape_code) + s->escape_code += V42BIS_ESC_STEP; + } + send_string(s); + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *ss) +{ + v42bis_comp_state_t *s; + int len; + + s = &ss->decompress; + len = s->string_length; + send_string(s); + s->flushed_length += len; + flush_octets(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode) +{ + s->compress.compression_mode = mode; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(v42bis_state_t *) v42bis_init(v42bis_state_t *s, + int negotiated_p0, + int negotiated_p1, + int negotiated_p2, + put_msg_func_t encode_handler, + void *encode_user_data, + int max_encode_len, + put_msg_func_t decode_handler, + void *decode_user_data, + int max_decode_len) +{ + int ret; + + if (negotiated_p1 < V42BIS_MIN_DICTIONARY_SIZE || negotiated_p1 > 65535) + return NULL; + if (negotiated_p2 < V42BIS_MIN_STRING_SIZE || negotiated_p2 > V42BIS_MAX_STRING_SIZE) + return NULL; + if (s == NULL) + { + if ((s = (v42bis_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + span_log_init(&s->logging, SPAN_LOG_NONE, NULL); + span_log_set_protocol(&s->logging, "V.42bis"); + + if ((ret = v42bis_comp_init(&s->compress, negotiated_p1, negotiated_p2, encode_handler, encode_user_data, max_encode_len))) + return NULL; + if ((ret = v42bis_comp_init(&s->decompress, negotiated_p1, negotiated_p2, decode_handler, decode_user_data, max_decode_len))) + { + comp_exit(&s->compress); + return NULL; + } + s->compress.v42bis_parm_p0 = negotiated_p0 & 2; + s->decompress.v42bis_parm_p0 = negotiated_p0 & 1; + + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s) +{ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s) +{ + comp_exit(&s->compress); + comp_exit(&s->decompress); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ -- To view, visit https://gerrit.osmocom.org/643 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iabedece9f97ca944a1e3f747bb073e532c4e9dca Gerrit-PatchSet: 35 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:18:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:18:00 +0000 Subject: [MERGED] openbsc[master]: RFC1144: integration and unit-test In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: RFC1144: integration and unit-test ...................................................................... RFC1144: integration and unit-test The previously pushed slhc implementation has been modified to compile and function outside of the kernel. Also debug log messages were added and datatypes ware matched. The implementation is now ready to be used Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am M openbsc/include/openbsc/debug.h R openbsc/include/openbsc/slhc.h M openbsc/src/gprs/Makefile.am M openbsc/src/gprs/sgsn_main.c M openbsc/src/gprs/slhc.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/slhc/Makefile.am A openbsc/tests/slhc/slhc_test.c A openbsc/tests/slhc/slhc_test.ok M openbsc/tests/testsuite.at 14 files changed, 543 insertions(+), 88 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 8ce3b70..e75b9eb 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -83,6 +83,7 @@ tests/mm_auth/mm_auth_test tests/xid/xid_test tests/sndcp_xid/sndcp_xid_test +tests/slhc/slhc_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 9dc2f8d..cebabdc 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -232,6 +232,7 @@ tests/mm_auth/Makefile tests/xid/Makefile tests/sndcp_xid/Makefile + tests/slhc/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index a91322f..12e1a66 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -65,6 +65,7 @@ sgsn.h \ signal.h \ silent_call.h \ + slhc.h \ smpp.h \ sms_queue.h \ socket.h \ diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 43ebb19..90ddca5 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -29,6 +29,7 @@ DBSSGP, DLLC, DSNDCP, + DSLHC, DNAT, DCTRL, DSMPP, diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc.h similarity index 97% rename from openbsc/include/openbsc/slhc_vj.h rename to openbsc/include/openbsc/slhc.h index 8716d59..cd5a47c 100644 --- a/openbsc/include/openbsc/slhc_vj.h +++ b/openbsc/include/openbsc/slhc.h @@ -171,7 +171,8 @@ #define NULLSLCOMPR (struct slcompress *)0 /* In slhc.c: */ -struct slcompress *slhc_init(int rslots, int tslots); +struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); + void slhc_free(struct slcompress *comp); int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, @@ -180,4 +181,7 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); int slhc_toss(struct slcompress *comp); +void slhc_i_status(struct slcompress *comp); +void slhc_o_status(struct slcompress *comp); + #endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3b58399..06c12d7 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -87,6 +87,7 @@ gprs_gsup_client.c \ sgsn_cdr.c \ sgsn_ares.c \ + slhc.c \ oap.c \ oap_messages.c \ gprs_llc_xid.c \ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 7d533c0..9f3260d 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -294,6 +294,11 @@ .description = "SCCP User Adaptation (SUA)", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DSLHC] = { + .name = "DSLHC", + .description = "RFC1144 TCP/IP Header compression (SLHC)", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, }; static const struct log_info gprs_log_info = { diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c index 27ed252..cbdf8db 100644 --- a/openbsc/src/gprs/slhc.c +++ b/openbsc/src/gprs/slhc.c @@ -50,61 +50,77 @@ * driver code belonging close to PPP and SLIP */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef CONFIG_INET -/* Entire module is for IP only */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#define ERR_PTR(x) x + static unsigned char *encode(unsigned char *cp, unsigned short n); static long decode(unsigned char **cpp); static unsigned char * put16(unsigned char *cp, unsigned short x); static unsigned short pull16(unsigned char **cpp); +/* Replacement for kernel space function ip_fast_csum() */ +static uint16_t ip_fast_csum(uint8_t *iph, int ihl) +{ + int i; + uint16_t temp; + uint32_t accumulator = 0xFFFF; + + for(i=0;i0xFFFF) + { + accumulator++; + accumulator&=0xFFFF; + } + } + + return (uint16_t)(htons(~accumulator)&0xFFFF); +} + +/* Replacement for kernel space function put_unaligned() */ +static void put_unaligned(uint16_t val, void *ptr) +{ + memcpy(ptr,&val,sizeof(val)); +} + + /* Allocate compression data structure * slots must be in range 0 to 255 (zero meaning no compression) * Returns pointer to structure or ERR_PTR() on error. */ struct slcompress * -slhc_init(int rslots, int tslots) +slhc_init(const void *ctx, int rslots, int tslots) { register short i; register struct cstate *ts; struct slcompress *comp; if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) - return ERR_PTR(-EINVAL); + return NULL; - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = (struct slcompress *)talloc_zero_size(ctx,sizeof(struct slcompress)); if (! comp) goto out_fail; if (rslots > 0) { size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = kzalloc(rsize, GFP_KERNEL); + comp->rstate = (struct cstate *) talloc_zero_size(ctx, rsize); if (! comp->rstate) goto out_free; comp->rslot_limit = rslots - 1; @@ -112,7 +128,7 @@ if (tslots > 0) { size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = kzalloc(tsize, GFP_KERNEL); + comp->tstate = (struct cstate *) talloc_zero_size(ctx, tsize); if (! comp->tstate) goto out_free2; comp->tslot_limit = tslots - 1; @@ -141,11 +157,11 @@ return comp; out_free2: - kfree(comp->rstate); + talloc_free(comp->rstate); out_free: - kfree(comp); + talloc_free(comp); out_fail: - return ERR_PTR(-ENOMEM); + return NULL; } @@ -153,16 +169,18 @@ void slhc_free(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_free(): Freeing compression states...\n"); + if ( comp == NULLSLCOMPR ) return; if ( comp->tstate != NULLSLSTATE ) - kfree( comp->tstate ); + talloc_free(comp->tstate ); if ( comp->rstate != NULLSLSTATE ) - kfree( comp->rstate ); + talloc_free( comp->rstate ); - kfree( comp ); + talloc_free( comp ); } @@ -187,6 +205,8 @@ } else { *cp++ = n; } + + DEBUGP(DSLHC, "encode(): n=%04x\n",n); return cp; } @@ -256,6 +276,7 @@ comp->sls_o_nontcp++; else comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Not a TCP packat, will not touch...\n"); return isize; } /* Extract TCP header */ @@ -271,6 +292,7 @@ ! (th->ack)){ /* TCP connection stuff; send as regular IP */ comp->sls_o_tcp++; + DEBUGP(DSLHC, "slhc_compress(): Packet is part of a TCP connection, will not touch...\n"); return isize; } /* @@ -287,6 +309,9 @@ * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ + + DEBUGP(DSLHC, "slhc_compress(): Compressible packet detected!\n"); + for ( ; ; ) { if( ip->saddr == cs->cs_ip.saddr && ip->daddr == cs->cs_ip.daddr @@ -310,11 +335,14 @@ * state points to the newest and we only need to set * xmit_oldest to update the lru linkage. */ + + DEBUGP(DSLHC, "slhc_compress(): Header not yet seen, will memorize header for the next turn...\n"); comp->sls_o_misses++; comp->xmit_oldest = lcs->cs_this; goto uncompressed; found: + DEBUGP(DSLHC, "slhc_compress(): Header already seen, trying to compress...\n"); /* * Found it -- move to the front on the connection list. */ @@ -344,6 +372,39 @@ */ oth = &cs->cs_tcp; + /* Display a little more debug information about which of the + * header fields changed unexpectedly */ + if(ip->version != cs->cs_ip.version) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->version != cs->cs_ip.version\n"); + if(ip->ihl != cs->cs_ip.ihl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ihl != cs->cs_ip.ihl\n"); + if(ip->tos != cs->cs_ip.tos) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->tos != cs->cs_ip.tos\n"); + if((ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))\n"); + if(ip->ttl != cs->cs_ip.ttl) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ttl != cs->cs_ip.ttl\n"); + if(th->doff != cs->cs_tcp.doff) + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: th->doff != cs->cs_tcp.doff\n"); + if(ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): ip->ihl = %i\n", ip->ihl); + DEBUGP(DSLHC, "slhc_compress(): ip+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(ip+1),((ip->ihl)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: cs->cs_ipopt = %s\n", + osmo_hexdump_nospc((uint8_t*)(cs->cs_ipopt),((ip->ihl)-5)*4)); + } + if(th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0) { + DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)\n"); + DEBUGP(DSLHC, "slhc_compress(): th->doff = %i\n", th->doff); + DEBUGP(DSLHC, "slhc_compress(): th+1 = %s\n", + osmo_hexdump_nospc((uint8_t*)(th+1),((th->doff)-5)*4)); + DEBUGP(DSLHC, "slhc_compress(): cs->cs_tcpopt = %s\n", + osmo_hexdump_nospc((uint8_t*)cs->cs_tcpopt, + ((th->doff)-5)*4)); + } + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl || ip->tos != cs->cs_ip.tos || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) @@ -351,6 +412,7 @@ || th->doff != cs->cs_tcp.doff || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + DEBUGP(DSLHC, "slhc_compress(): The header contains unexpected changes, can't compress...\n"); goto uncompressed; } @@ -362,6 +424,7 @@ */ if(th->urg){ deltaS = ntohs(th->urg_ptr); + DEBUGP(DSLHC, "slhc_compress(): flag: Urgent Pointer (U) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_U; } else if(th->urg_ptr != oth->urg_ptr){ @@ -369,21 +432,29 @@ * implementation should never do this but RFC793 * doesn't prohibit the change so we have to deal * with it. */ + DEBUGP(DSLHC, "slhc_compress(): URG not set but urp changed, can't compress...\n"); goto uncompressed; } if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Window (W) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_W; } if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ - if(deltaA > 0x0000ffff) + if(deltaA > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Ack (A) = 1\n"); cp = encode(cp,deltaA); changes |= NEW_A; } if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ - if(deltaS > 0x0000ffff) + if(deltaS > 0x0000ffff) { + DEBUGP(DSLHC, "slhc_compress(): (deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L, can't compress...\n"); goto uncompressed; + } + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_S; } @@ -399,17 +470,21 @@ if(ip->tot_len != cs->cs_ip.tot_len && ntohs(cs->cs_ip.tot_len) == hlen) break; + DEBUGP(DSLHC, "slhc_compress(): Retransmitted packet detected, can't compress...\n"); goto uncompressed; case SPECIAL_I: case SPECIAL_D: /* actual changes match one of our special case encodings -- * send packet uncompressed. */ + DEBUGP(DSLHC, "slhc_compress(): Special case detected, can't compress...\n"); goto uncompressed; case NEW_S|NEW_A: if(deltaS == deltaA && deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_compress(): Special case for echoed terminal traffic detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_I; cp = new_seq; } @@ -417,6 +492,8 @@ case NEW_S: if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ /* special case for data xfer */ + DEBUGP(DSLHC, "slhc_compress(): Special case for data xfer detected...\n"); + DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Ack (A) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); changes = SPECIAL_D; cp = new_seq; } @@ -424,11 +501,14 @@ } deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); if(deltaS != 1){ + DEBUGP(DSLHC, "slhc_compress(): flag: Delta IP ID (I) = 1\n"); cp = encode(cp,deltaS); changes |= NEW_I; } - if(th->psh) + if(th->psh) { + DEBUGP(DSLHC, "slhc_compress(): flag: Push (P) = 1\n"); changes |= TCP_PUSH_BIT; + } /* Grab the cksum before we overwrite it below. Then update our * state with this packet's header. */ @@ -445,6 +525,7 @@ if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ cp = ocp; *cpp = ocp; + DEBUGP(DSLHC, "slhc_compress(): flag: Connection number (C) = 1\n"); *cp++ = changes | NEW_C; *cp++ = cs->cs_this; comp->xmit_current = cs->cs_this; @@ -456,6 +537,10 @@ *(__sum16 *)cp = csum; cp += 2; /* deltaS is now the size of the change section of the compressed header */ + + DEBUGP(DSLHC, "slhc_compress(): Delta-list length (deltaS) = %li\n",deltaS); + DEBUGP(DSLHC, "slhc_compress(): Original header len (hlen) = %i\n",hlen); + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ memcpy(cp+deltaS,icp+hlen,isize-hlen); comp->sls_o_compressed++; @@ -467,6 +552,7 @@ * to use on future compressed packets in the protocol field). */ uncompressed: + DEBUGP(DSLHC, "slhc_compress(): Packet will be sent uncompressed...\n"); memcpy(&cs->cs_ip,ip,20); memcpy(&cs->cs_tcp,th,20); if (ip->ihl > 5) @@ -538,6 +624,8 @@ switch(changes & SPECIALS_MASK){ case SPECIAL_I: /* Echoed terminal traffic */ + DEBUGP(DSLHC, "slhc_uncompress(): Echoed terminal traffic detected\n"); + { register short i; i = ntohs(ip->tot_len) - hdrlen; @@ -547,11 +635,13 @@ break; case SPECIAL_D: /* Unidirectional data */ + DEBUGP(DSLHC, "slhc_uncompress(): Unidirectional data detected\n"); thp->seq = htonl( ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen); break; default: + DEBUGP(DSLHC, "slhc_uncompress(): default packet type detected\n"); if(changes & NEW_U){ thp->urg = 1; if((x = decode(&cp)) == -1) { @@ -601,6 +691,7 @@ ip->tot_len = htons(len); ip->check = 0; + DEBUGP(DSLHC, "slhc_uncompress(): making space for the reconstructed header...\n"); memmove(icp + hdrlen, cp, len - hdrlen); cp = icp; @@ -625,6 +716,7 @@ return len; bad: + DEBUGP(DSLHC, "slhc_uncompress(): bad packet detected!\n"); comp->sls_i_error++; return slhc_toss( comp ); } @@ -641,6 +733,7 @@ if(isize < 20) { /* The packet is shorter than a legal IP header */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The packet is shorter than a legal IP header ==> slhc_toss()\n"); return slhc_toss( comp ); } /* Peek at the IP header's IHL field to find its length */ @@ -648,6 +741,7 @@ if(ihl < 20 / 4){ /* The IP header length field is too small */ comp->sls_i_runt++; + DEBUGP(DSLHC, "slhc_remember(): The IP header length field is too small ==> slhc_toss()\n"); return slhc_toss( comp ); } index = icp[9]; @@ -656,10 +750,12 @@ if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; + DEBUGP(DSLHC, "slhc_remember(): Bad IP header checksum; discard ==> slhc_toss()\n"); return slhc_toss( comp ); } if(index > comp->rslot_limit) { comp->sls_i_error++; + DEBUGP(DSLHC, "slhc_remember(): index > comp->rslot_limit ==> slhc_toss()\n"); return slhc_toss(comp); } @@ -683,6 +779,7 @@ int slhc_toss(struct slcompress *comp) { + DEBUGP(DSLHC, "slhc_toss(): Reset compression state...\n"); if ( comp == NULLSLCOMPR ) return 0; @@ -690,55 +787,27 @@ return 0; } -#else /* CONFIG_INET */ - -int -slhc_toss(struct slcompress *comp) +void slhc_i_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); - return -EINVAL; -} -int -slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); - return -EINVAL; -} -int -slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_i_status(): %d Cmp, %d Uncmp, %d Bad, %d Tossed\n", + comp->sls_i_compressed, + comp->sls_i_uncompressed, + comp->sls_i_error, + comp->sls_i_tossed); + } } -int -slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +void slhc_o_status(struct slcompress *comp) { - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); - return -EINVAL; + if (comp != NULLSLCOMPR) { + DEBUGP(DSLHC, "slhc_o_status(): %d Cmp, %d Uncmp, %d AsIs, %d NotTCP %d Searches, %d Misses\n", + comp->sls_o_compressed, + comp->sls_o_uncompressed, + comp->sls_o_tcp, + comp->sls_o_nontcp, + comp->sls_o_searches, + comp->sls_o_misses); + } } -void -slhc_free(struct slcompress *comp) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); -} -struct slcompress * -slhc_init(int rslots, int tslots) -{ - printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); - return NULL; -} - -#endif /* CONFIG_INET */ - -/* VJ header compression */ -EXPORT_SYMBOL(slhc_init); -EXPORT_SYMBOL(slhc_free); -EXPORT_SYMBOL(slhc_remember); -EXPORT_SYMBOL(slhc_compress); -EXPORT_SYMBOL(slhc_uncompress); -EXPORT_SYMBOL(slhc_toss); - -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 7b145f7..2e342e0 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -11,6 +11,7 @@ mm_auth \ xid \ sndcp_xid \ + slhc \ $(NULL) if BUILD_NAT diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index cf88101..bab3f0e 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -58,6 +58,7 @@ $(top_builddir)/src/gprs/oap_messages.o \ $(top_builddir)/src/gprs/gprs_llc_xid.o \ $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(top_builddir)/src/gprs/slhc.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ diff --git a/openbsc/tests/slhc/Makefile.am b/openbsc/tests/slhc/Makefile.am new file mode 100644 index 0000000..32a3cc4 --- /dev/null +++ b/openbsc/tests/slhc/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = slhc_test.ok + +noinst_PROGRAMS = slhc_test + +slhc_test_SOURCES = slhc_test.c + +slhc_test_LDADD = \ + $(top_builddir)/src/gprs/slhc.o \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(LIBOSMOCORE_LIBS) + + diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c new file mode 100644 index 0000000..59a5425 --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.c @@ -0,0 +1,298 @@ +/* Test SLHC/RFC1144 TCP/IP Header compression/decompression */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +/* Number of compression slots (S0-1) */ +#define SLOTS 8 + +/* Maximum packet bytes to display */ +#define DISP_MAX_BYTES 100 + +/* Sample packets to test with */ +#define PACKETS_LEN 6 +char *packets[] = { + "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", + "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", + "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", + "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" +}; + +/* Compress a packet using Van Jacobson RFC1144 header compression */ +static int compress(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + uint8_t *comp_ptr; /* Not used */ + int compr_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Run compressor */ + compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); + return compr_len; +} + +/* Expand a packet using Van Jacobson RFC1144 header compression */ +static int expand(uint8_t *data_o, uint8_t *data_i, int len, + struct slcompress *comp) +{ + int data_decompressed_len; + + /* Create a working copy of the incoming data */ + memcpy(data_o, data_i, len); + + /* Handle an uncompressed packet (learn header information */ + if ((data_i[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { + data_o[0] &= 0x4F; + data_decompressed_len = slhc_remember(comp, data_o, len); + return data_decompressed_len; + } + + /* Uncompress compressed packets */ + else if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { + data_decompressed_len = slhc_uncompress(comp, data_o, len); + return data_decompressed_len; + } + + /* Regular or unknown packets will not be touched */ + return len; +} + +/* Calculate IP Header checksum */ +static uint16_t calc_ip_csum(uint8_t *data, int len) +{ + int i; + uint32_t accumulator = 0; + uint16_t *pointer = (uint16_t *) data; + + for (i = len; i > 1; i -= 2) { + accumulator += *pointer; + pointer++; + } + + if (len % 2) + accumulator += *pointer; + + accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); + accumulator += (accumulator >> 16) & 0xffff; + return (~accumulator); +} + +/* Calculate TCP/IP checksum */ +static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) +{ + uint8_t *buf; + uint16_t csum; + + buf = talloc_zero_size(ctx, len); + memset(buf, 0, len); + memcpy(buf, packet + 12, 8); + buf[9] = packet[9]; + buf[11] = (len - 20) & 0xFF; + buf[10] = (len - 20) >> 8 & 0xFF; + memcpy(buf + 12, packet + 20, len - 20); + csum = calc_ip_csum(buf, len - 20 + 12); + talloc_free(buf); + return csum; +} + +/* Check TCP/IP packet */ +static void check_packet(const void *ctx, uint8_t *packet, int len) +{ + /* Check IP header */ + OSMO_ASSERT(len > 20); + OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + + /* Check TCP packet */ + if (packet[9] != 0x06) + return; + OSMO_ASSERT(len > 40); + OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); +} + +/* Strip TCP options from TCP/IP packet */ +static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) +{ + uint8_t doff; + uint16_t csum; + + /* Check if the packet can be handled here */ + if (len < 37) + return len; + if (packet[9] != 0x06) + return len; + + /* Strip TCP/IP options from packet */ + doff = ((packet[32] >> 4) & 0x0F) * 4; + memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); + len = len - (doff - 20); + + /* Repair data offset (TCP header length) */ + packet[32] &= 0x0F; + packet[32] |= 0x50; + + /* Repair checksum */ + packet[36] = 0; + packet[37] = 0; + csum = calc_tcpip_csum(ctx, packet, len); + packet[36] = csum & 0xFF; + packet[37] = csum >> 8 & 0xFF; + + /* Repair total length */ + packet[3] = len & 0xFF; + packet[2] = len >> 8 & 0xFF; + + /* Repair IP header checksum */ + packet[10] = 0; + packet[11] = 0; + csum = calc_ip_csum(packet, 20); + packet[10] = csum & 0xFF; + packet[11] = csum >> 8 & 0xFF; + printf("csum=%04x\n", csum); + + return len; +} + +/* Compress / Decompress packets */ +static void test_slhc(const void *ctx) +{ + char packet_ascii[2048]; + int i; + + struct slcompress *comp; + uint8_t packet[1024]; + int packet_len; + uint8_t packet_compr[1024]; + int packet_compr_len; + uint8_t packet_decompr[1024]; + int packet_decompr_len; + + printf("Allocating compression state...\n"); + comp = slhc_init(ctx, SLOTS, SLOTS); + OSMO_ASSERT(comp); + + for(i=0;i DISP_MAX_BYTES) + packet_compr_len = DISP_MAX_BYTES; + if (packet_len > DISP_MAX_BYTES) + packet_len = DISP_MAX_BYTES; + if (packet_decompr_len > DISP_MAX_BYTES) + packet_decompr_len = DISP_MAX_BYTES; + printf("Original Packet: (%i bytes) %s\n", packet_len, + osmo_hexdump_nospc(packet, packet_len)); + printf("DecompressedPacket: (%i bytes) %s\n", + packet_decompr_len, osmo_hexdump_nospc(packet_decompr, + packet_decompr_len)); + printf("CompressedPacket: (%i bytes) %s\n", packet_compr_len, + osmo_hexdump_nospc(packet_compr, packet_compr_len)); + slhc_o_status(comp); + slhc_o_status(comp); + + printf("\n"); + } + + printf("Freeing compression state...\n"); + slhc_free(comp); + printf("\n"); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + }, + [DSLHC] = { + .name = "DSLHC", + .description = + "Van Jacobson RFC1144 TCP/IP header compression (SLHC)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *ctx; + + osmo_init_logging(&info); + + ctx = talloc_named_const(NULL, 0, "slhc_ctx"); + + test_slhc(ctx); + + printf("Done\n"); + + talloc_report_full(ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/slhc/slhc_test.ok b/openbsc/tests/slhc/slhc_test.ok new file mode 100644 index 0000000..636241d --- /dev/null +++ b/openbsc/tests/slhc/slhc_test.ok @@ -0,0 +1,52 @@ +Allocating compression state... +csum=b3a9 +Compressing... +Decompressing... +Results: +Original Packet: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +DecompressedPacket: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 +CompressedPacket: (52 bytes) 7510003446dd40004000a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 + +csum=97a9 +Compressing... +Decompressing... +Results: +Original Packet: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +DecompressedPacket: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 +CompressedPacket: (43 bytes) df00cda4fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 + +csum=baa9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +DecompressedPacket: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 +CompressedPacket: (9 bytes) dc00a70a5227fffd01 + +csum=b9a9 +Compressing... +Decompressing... +Results: +Original Packet: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +DecompressedPacket: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 +CompressedPacket: (7 bytes) db00a706fffb01 + +csum=7ba9 +Compressing... +Decompressing... +Results: +Original Packet: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +DecompressedPacket: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +CompressedPacket: (68 bytes) db00c2d00d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a + +csum=aca9 +Compressing... +Decompressing... +Results: +Original Packet: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +DecompressedPacket: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 +CompressedPacket: (18 bytes) df0021fb706f6c6c7578206c6f67696e3a20 + +Freeing compression state... + +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 85a81d6..5f37b8e 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -136,3 +136,8 @@ AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([slhc]) +AT_KEYWORDS([slhc]) +cat $abs_srcdir/slhc/slhc_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/635 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7a638e88a43b3eb9d006751a03ef2570e36613f0 Gerrit-PatchSet: 20 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:18:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:18:00 +0000 Subject: [MERGED] openbsc[master]: SNDCP: add SNDCP-XID encoder/decoder and unit test In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SNDCP: add SNDCP-XID encoder/decoder and unit test ...................................................................... SNDCP: add SNDCP-XID encoder/decoder and unit test The SNDCP-XID (or layer-3 xid) is used to exchange layer-3 parameters such as compression. The encoder encodes a bytestream that is then sent as regular XID field from LLC. We will need the SNDCP-XID to negotiate the parameters for our upcomming GPRS data and header compression features Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e --- M openbsc/.gitignore M openbsc/configure.ac M openbsc/include/openbsc/Makefile.am A openbsc/include/openbsc/gprs_sndcp_xid.h M openbsc/src/gprs/Makefile.am A openbsc/src/gprs/gprs_sndcp_xid.c M openbsc/tests/Makefile.am M openbsc/tests/sgsn/Makefile.am A openbsc/tests/sndcp_xid/Makefile.am A openbsc/tests/sndcp_xid/sndcp_xid_test.c A openbsc/tests/sndcp_xid/sndcp_xid_test.ok M openbsc/tests/testsuite.at 12 files changed, 2,350 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/.gitignore b/openbsc/.gitignore index 518a960..8ce3b70 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -82,6 +82,7 @@ tests/gtphub/gtphub_test tests/mm_auth/mm_auth_test tests/xid/xid_test +tests/sndcp_xid/sndcp_xid_test tests/atconfig tests/atlocal diff --git a/openbsc/configure.ac b/openbsc/configure.ac index f63d61f..9dc2f8d 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -231,6 +231,7 @@ tests/gtphub/Makefile tests/mm_auth/Makefile tests/xid/Makefile + tests/sndcp_xid/Makefile doc/Makefile doc/examples/Makefile Makefile) diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index cae8ba4..a91322f 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -25,6 +25,7 @@ gprs_llc_xid.h \ gprs_sgsn.h \ gprs_sndcp.h \ + gprs_sndcp_xid.h \ gprs_utils.h \ gsm_04_08.h \ gsm_04_11.h \ diff --git a/openbsc/include/openbsc/gprs_sndcp_xid.h b/openbsc/include/openbsc/gprs_sndcp_xid.h new file mode 100644 index 0000000..02904a7 --- /dev/null +++ b/openbsc/include/openbsc/gprs_sndcp_xid.h @@ -0,0 +1,216 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include + +#define CURRENT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ +#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit + * for compression enitity number */ + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ +#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ + +/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control + * information compression field (Figure 7) and 3GPP TS 44.065, + * 6.6.1.1 Format of the data compression field (Figure 9) */ +struct gprs_sndcp_comp_field { + struct llist_head list; + + /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ + unsigned int p; + + /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int entity; + + /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ + int algo; + + /* Number of contained PCOMP / DCOMP values */ + uint8_t comp_len; + + /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ + uint8_t comp[MAX_COMP]; + + /* Note: Only one of the following struct pointers may, + be used. Unused pointers must be set to NULL! */ + struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; + struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; + struct gprs_sndcp_pcomp_rohc_params *rohc_params; + struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; + struct gprs_sndcp_dcomp_v44_params *v44_params; +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_hdr_comp_algo { + RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ + RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ + ROHC /* Robust Header Compression, see also 6.5.4 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_data_comp_algo { + V42BIS, /* V.42bis data compression, see also 6.6.2 */ + V44 /* V44 data compression, see also: 6.6.3 */ +}; + +/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ +enum gprs_sndcp_xid_param_types { + SNDCP_XID_VERSION_NUMBER, + SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ + SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ +struct gprs_sndcp_pcomp_rfc1144_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int s01; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ +enum gprs_sndcp_pcomp_rfc1144_pcomp { + RFC1144_PCOMP1, /* Uncompressed TCP */ + RFC1144_PCOMP2, /* Compressed TCP */ + RFC1144_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ +struct gprs_sndcp_pcomp_rfc2507_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int f_max_period; /* (default 256) */ + int f_max_time; /* (default 5) */ + int max_header; /* (default 168) */ + int tcp_space; /* (default 15) */ + int non_tcp_space; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ +enum gprs_sndcp_pcomp_rfc2507_pcomp { + RFC2507_PCOMP1, /* Full Header */ + RFC2507_PCOMP2, /* Compressed TCP */ + RFC2507_PCOMP3, /* Compressed TCP non delta */ + RFC2507_PCOMP4, /* Compressed non TCP */ + RFC2507_PCOMP5, /* Context state */ + RFC2507_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ +struct gprs_sndcp_pcomp_rohc_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int max_cid; /* (default 15) */ + int max_header; /* (default 168) */ + uint8_t profile_len; /* (default 1) */ + uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ +enum gprs_sndcp_pcomp_rohc_pcomp { + ROHC_PCOMP1, /* ROHC small CIDs */ + ROHC_PCOMP2, /* ROHC large CIDs */ + ROHC_PCOMP_NUM /* Number of pcomp values */ +}; + +/* ROHC compression profiles, see also: + http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ +enum gprs_sndcp_xid_rohc_profiles { + ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ + ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ + ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ + ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ + ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ + ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ + ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ + ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ + ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ + ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ + ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ + ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ + ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ + ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ + ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ + ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ +}; + +/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ +struct gprs_sndcp_dcomp_v42bis_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int p0; /* (default 3) */ + int p1; /* (default 2048) */ + int p2; /* (default 20) */ + +}; + +/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v42bis_dcomp { + V42BIS_DCOMP1, /* V.42bis enabled */ + V42BIS_DCOMP_NUM /* Number of dcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ +struct gprs_sndcp_dcomp_v44_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int c0; /* (default 10000000) */ + int p0; /* (default 3) */ + int p1t; /* Refer to subclause 6.6.3.1.4 */ + int p1r; /* Refer to subclause 6.6.3.1.5 */ + int p3t; /* (default 3 x p1t) */ + int p3r; /* (default 3 x p1r) */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v44_dcomp { + V44_DCOMP1, /* Packet method compressed */ + V44_DCOMP2, /* Multi packet method compressed */ + V44_DCOMP_NUM /* Number of dcomp values */ +}; + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields); + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t * src, + unsigned int src_len, + const struct llist_head *comp_fields_req); + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class( + const struct gprs_sndcp_comp_field *comp_field); + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl); + diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 59136bd..3b58399 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -72,6 +72,7 @@ gprs_sgsn.c \ gprs_sndcp.c \ gprs_sndcp_vty.c \ + gprs_sndcp_xid.c \ sgsn_main.c \ sgsn_vty.c \ sgsn_libgtp.c \ @@ -98,6 +99,7 @@ $(LIBCRYPTO_LIBS) \ -lrt \ -lgtp \ + -lm \ $(NULL) if BUILD_IU osmo_sgsn_LDADD += \ diff --git a/openbsc/src/gprs/gprs_sndcp_xid.c b/openbsc/src/gprs/gprs_sndcp_xid.c new file mode 100644 index 0000000..270bdee --- /dev/null +++ b/openbsc/src/gprs/gprs_sndcp_xid.c @@ -0,0 +1,1803 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* When the propose bit in an SNDCP-XID compression field is set to zero, + * the algorithm identifier is stripped. The algoritm parameters are specific + * for each algorithms. The following struct is used to pass the information + * about the referenced algorithm to the parser. */ +struct entity_algo_table { + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */ + unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or + SNDCP_XID_PROTOCOL_COMPRESSION */ +}; + +/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */ + +/* Encode applicable sapis (works the same in all three compression schemes) */ +static int encode_pcomp_applicable_sapis(uint8_t *dst, + const uint8_t *nsapis, + uint8_t nsapis_len) +{ + /* NOTE: Buffer *dst needs offer at 2 bytes + * of space to store the generation results */ + + uint16_t blob; + uint8_t nsapi; + int i; + + /* Bail if number of possible nsapis exceeds valid range + * (Only 11 nsapis possible for PDP-Contexts) */ + OSMO_ASSERT(nsapis_len <= 11); + + /* Encode applicable SAPIs */ + blob = 0; + for (i = 0; i < nsapis_len; i++) { + nsapi = nsapis[i]; + /* Only NSAPI 5 to 15 are applicable for user traffic (PDP- + * contexts). Only for these NSAPIs SNDCP-XID parameters + * can apply. See also 3GPP TS 44.065, 5.1 Service primitives */ + OSMO_ASSERT(nsapi >= 5 && nsapi <= 15); + blob |= (1 << nsapi); + } + + /* Store result */ + *dst = (blob >> 8) & 0xFF; + dst++; + *dst = blob & 0xFF; + + return 2; +} + +/* Encode rfc1144 parameter field + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int encode_pcomp_rfc1144_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc1144_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 3); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode s01 (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + OSMO_ASSERT(params->s01 >= 0); + OSMO_ASSERT(params->s01 <= 255); + *dst = params->s01; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* + * Encode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) + */ +static int encode_pcomp_rfc2507_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_pcomp_rfc2507_params *params) +{ + /* NOTE: Buffer *dst should offer at least 3 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 9); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_period >= 1); + OSMO_ASSERT(params->f_max_period <= 65535); + *dst = (params->f_max_period >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->f_max_period) & 0xFF; + dst++; + dst_counter++; + + /* Encode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->f_max_time >= 1); + OSMO_ASSERT(params->f_max_time <= 255); + *dst = params->f_max_time; + dst++; + dst_counter++; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = params->max_header; + dst++; + dst_counter++; + + /* Encode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->tcp_space >= 3); + OSMO_ASSERT(params->tcp_space <= 255); + *dst = params->tcp_space; + dst++; + dst_counter++; + + /* Encode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + OSMO_ASSERT(params->non_tcp_space >= 3); + OSMO_ASSERT(params->non_tcp_space <= 65535); + *dst = (params->non_tcp_space >> 8) & 0xFF; + dst++; + dst_counter++; + *dst = (params->non_tcp_space) & 0xFF; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode ROHC parameter field + * (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int encode_pcomp_rohc_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_pcomp_rohc_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 36 + * (2 * 16 Profiles + 2 * 3 Parameter) bytes + * of memory space to store generation results */ + + int i; + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 38); + + /* Bail if number of ROHC profiles exceeds limit + * (ROHC supports only a maximum of 16 different profiles) */ + OSMO_ASSERT(params->profile_len >= 0); + OSMO_ASSERT(params->profile_len <= 16); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_cid >= 0); + OSMO_ASSERT(params->max_cid <= 16383); + *dst = (params->max_cid >> 8) & 0xFF; + dst++; + *dst = params->max_cid & 0xFF; + dst++; + dst_counter += 2; + + /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + OSMO_ASSERT(params->max_header >= 60); + OSMO_ASSERT(params->max_header <= 255); + *dst = (params->max_header >> 8) & 0xFF; + dst++; + *dst = params->max_header & 0xFF; + dst++; + dst_counter += 2; + + /* Encode ROHC Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < params->profile_len; i++) { + *dst = (params->profile[i] >> 8) & 0xFF; + dst++; + *dst = params->profile[i] & 0xFF; + dst++; + dst_counter += 2; + } + + /* Return generated length */ + return dst_counter; +} + +/* Encode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int encode_dcomp_v42bis_params(uint8_t *dst, unsigned int dst_maxlen, + const struct + gprs_sndcp_dcomp_v42bis_params *params) +{ + /* NOTE: Buffer *dst should offer at least 6 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 6); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p1 >= 512); + OSMO_ASSERT(params->p1 <= 65535); + *dst = (params->p1 >> 8) & 0xFF; + dst++; + *dst = params->p1 & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + OSMO_ASSERT(params->p2 >= 6); + OSMO_ASSERT(params->p2 <= 250); + *dst = params->p2; + dst++; + dst_counter++; + + /* Return generated length */ + return dst_counter; +} + +/* Encode V44 parameter field + * (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int encode_dcomp_v44_params(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_dcomp_v44_params + *params) +{ + /* NOTE: Buffer *dst should offer at least 12 bytes + * of space to store the generation results */ + + int dst_counter = 0; + int rc; + + OSMO_ASSERT(dst_maxlen >= 12); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode applicable SAPIs */ + rc = encode_pcomp_applicable_sapis(dst, params->nsapi, + params->nsapi_len); + dst += rc; + dst_counter += rc; + + /* Encode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->c0 == 0x80 || params->c0 == 0xC0); + *dst = params->c0 & 0xC0; + dst++; + dst_counter++; + + /* Encode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p0 >= 0); + OSMO_ASSERT(params->p0 <= 3); + *dst = params->p0 & 0x03; + dst++; + dst_counter++; + + /* Encode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1t >= 256); + OSMO_ASSERT(params->p1t <= 65535); + *dst = (params->p1t >> 8) & 0xFF; + dst++; + *dst = params->p1t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p1r >= 256); + OSMO_ASSERT(params->p1r <= 65535); + *dst = (params->p1r >> 8) & 0xFF; + dst++; + *dst = params->p1r & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3t >= 0); + OSMO_ASSERT(params->p3t <= 65535); + OSMO_ASSERT(params->p3t >= 2 * params->p1t); + *dst = (params->p3t >> 8) & 0xFF; + dst++; + *dst = params->p3t & 0xFF; + dst++; + dst_counter += 2; + + /* Encode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + OSMO_ASSERT(params->p3r >= 0); + OSMO_ASSERT(params->p3r <= 65535); + OSMO_ASSERT(params->p3r >= 2 * params->p1r); + *dst = (params->p3r >> 8) & 0xFF; + dst++; + *dst = params->p3r & 0xFF; + dst++; + dst_counter += 2; + + /* Return generated length */ + return dst_counter; +} + +/* Encode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen, + const struct gprs_sndcp_comp_field *comp_field) +{ + int dst_counter = 0; + int len; + int expected_length; + int i; + + uint8_t payload_bytes[256]; + int payload_bytes_len = -1; + + /* If possible, try do encode payload bytes first */ + if (comp_field->rfc1144_params) { + payload_bytes_len = + encode_pcomp_rfc1144_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc1144_params); + } else if (comp_field->rfc2507_params) { + payload_bytes_len = + encode_pcomp_rfc2507_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rfc2507_params); + } else if (comp_field->rohc_params) { + payload_bytes_len = + encode_pcomp_rohc_params(payload_bytes, + sizeof(payload_bytes), + comp_field->rohc_params); + } else if (comp_field->v42bis_params) { + payload_bytes_len = + encode_dcomp_v42bis_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v42bis_params); + } else if (comp_field->v44_params) { + payload_bytes_len = + encode_dcomp_v44_params(payload_bytes, + sizeof(payload_bytes), + comp_field->v44_params); + } else + OSMO_ASSERT(false); + + /* Bail immediately if payload byte generation failed */ + OSMO_ASSERT(payload_bytes_len >= 0); + + /* Bail if comp_len is out of bounds */ + OSMO_ASSERT(comp_field->comp_len <= sizeof(comp_field->comp)); + + /* Calculate length field of the data block */ + if (comp_field->p) { + len = + payload_bytes_len + + ceil((double)(comp_field->comp_len) / 2.0); + expected_length = len + 3; + } else { + len = payload_bytes_len; + expected_length = len + 2; + } + + /* Bail immediately if no sufficient memory space is supplied */ + OSMO_ASSERT(dst_maxlen >= expected_length); + + /* Check if the entity number is within bounds */ + OSMO_ASSERT(comp_field->entity <= 0x1f); + + /* Check if the algorithm number is within bounds */ + OSMO_ASSERT(comp_field->algo >= 0 || comp_field->algo <= 0x1f); + + /* Zero out buffer */ + memset(dst, 0, dst_maxlen); + + /* Encode Propose bit */ + if (comp_field->p) + *dst |= (1 << 7); + + /* Encode entity number */ + *dst |= comp_field->entity & 0x1F; + dst++; + dst_counter++; + + /* Encode algorithm number */ + if (comp_field->p) { + *dst |= comp_field->algo & 0x1F; + dst++; + dst_counter++; + } + + /* Encode length field */ + *dst |= len & 0xFF; + dst++; + dst_counter++; + + /* Encode PCOMP/DCOMP values */ + if (comp_field->p) { + for (i = 0; i < comp_field->comp_len; i++) { + /* Check if submitted PCOMP/DCOMP + values are within bounds */ + if ((comp_field->comp[i] < 0) + || (comp_field->comp[i] > 0x0F)) + return -EINVAL; + + if (i & 1) { + *dst |= comp_field->comp[i] & 0x0F; + dst++; + dst_counter++; + } else + *dst |= (comp_field->comp[i] << 4) & 0xF0; + } + + if (i & 1) { + dst++; + dst_counter++; + } + } + + /* Append payload bytes */ + memcpy(dst, payload_bytes, payload_bytes_len); + dst_counter += payload_bytes_len; + + /* Return generated length */ + return dst_counter; +} + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field + *comp_field) +{ + OSMO_ASSERT(comp_field); + + if (comp_field->rfc1144_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rfc2507_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->rohc_params) + return SNDCP_XID_PROTOCOL_COMPRESSION; + else if (comp_field->v42bis_params) + return SNDCP_XID_DATA_COMPRESSION; + else if (comp_field->v44_params) + return SNDCP_XID_DATA_COMPRESSION; + else + return -EINVAL; +} + +/* Convert all compression fields to bytstreams */ +static int gprs_sndcp_pack_fields(const struct llist_head *comp_fields, + uint8_t *dst, + unsigned int dst_maxlen, int class) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int rc; + + llist_for_each_entry_reverse(comp_field, comp_fields, list) { + if (class == gprs_sndcp_get_compression_class(comp_field)) { + rc = encode_comp_field(dst + byte_counter, + dst_maxlen - byte_counter, + comp_field); + + /* When input data is correct, there is + * no reason for the encoder to fail! */ + OSMO_ASSERT(rc >= 0); + + byte_counter += rc; + } + } + + /* Return generated length */ + return byte_counter; +} + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields) +{ + int rc; + int byte_counter = 0; + uint8_t comp_bytes[512]; + uint8_t xid_version_number[1] = { CURRENT_SNDCP_VERSION }; + + OSMO_ASSERT(comp_fields); + OSMO_ASSERT(dst); + OSMO_ASSERT(dst_maxlen >= 2 + sizeof(xid_version_number)); + + /* Bail if there is no input */ + if (llist_empty(comp_fields)) + return -EINVAL; + + /* Prepend header */ + dst = + tlv_put(dst, SNDCP_XID_VERSION_NUMBER, + sizeof(xid_version_number), xid_version_number); + byte_counter += (sizeof(xid_version_number) + 2); + + /* Add data compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_DATA_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_DATA_COMPRESSION, rc, comp_bytes); + byte_counter += rc + 2; + } + + /* Add header compression fields */ + rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, + sizeof(comp_bytes), + SNDCP_XID_PROTOCOL_COMPRESSION); + OSMO_ASSERT(rc >= 0); + + if (rc > 0) { + dst = tlv_put(dst, SNDCP_XID_PROTOCOL_COMPRESSION, rc, + comp_bytes); + byte_counter += rc + 2; + } + + /* Return generated length */ + return byte_counter; +} + +/* FUNCTIONS RELATED TO SNDCP-XID DECODING */ + +/* Decode applicable sapis (works the same in all three compression schemes) */ +static int decode_pcomp_applicable_sapis(uint8_t *nsapis, + uint8_t *nsapis_len, + const uint8_t *src, + unsigned int src_len) +{ + uint16_t blob; + int i; + int nsapi_len = 0; + + /* Exit immediately if no result can be stored */ + if (!nsapis) + return -EINVAL; + + /* Exit immediately if not enough input data is available */ + if (src_len < 2) + return -EINVAL; + + /* Read bitmask */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= (*src) & 0xFF; + blob = (blob >> 5); + + /* Decode applicable SAPIs */ + for (i = 0; i < 15; i++) { + if ((blob >> i) & 1) { + nsapis[nsapi_len] = i + 5; + nsapi_len++; + } + } + + /* Return consumed length */ + *nsapis_len = nsapi_len; + return 2; +} + +/* Decode 16 bit field */ +static int decode_pcomp_16_bit_field(int *value_int, uint16_t * value_uint16, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint16_t blob; + + /* Reset values to zero (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint16) + *value_uint16 = 0; + + /* Exit if not enough src are available */ + if (src_len < 2) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + blob = (blob << 8) & 0xFF00; + src++; + blob |= *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint16) + *value_uint16 = blob; + + /* Return consumed length */ + return 2; +} + +/* Decode 8 bit field */ +static int decode_pcomp_8_bit_field(int *value_int, uint8_t *value_uint8, + const uint8_t *src, + unsigned int src_len, + int value_min, int value_max) +{ + uint8_t blob; + + /* Reset values to invalid (just to be sure) */ + if (value_int) + *value_int = -1; + if (value_uint8) + *value_uint8 = 0; + + /* Exit if not enough src are available */ + if (src_len < 1) + return -EINVAL; + + /* Decode bit value */ + blob = *src; + + /* Check if parsed value is within bounds */ + if (blob < value_min) + return -EINVAL; + if (blob > value_max) + return -EINVAL; + + /* Hand back results to the caller */ + if (value_int) + *value_int = blob; + if (value_uint8) + *value_uint8 = blob; + + /* Return consumed length */ + return 1; +} + +/* Decode rfc1144 parameter field see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ +static int decode_pcomp_rfc1144_params(struct gprs_sndcp_pcomp_rfc1144_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->s01 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode parameter S0 -1 + * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ + rc = decode_pcomp_8_bit_field(¶ms->s01, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode rfc2507 parameter field + * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ +static int decode_pcomp_rfc2507_params(struct gprs_sndcp_pcomp_rfc2507_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->f_max_period = -1; + params->f_max_time = -1; + params->max_header = -1; + params->tcp_space = -1; + params->non_tcp_space = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->f_max_period, NULL, src, + src_len - byte_counter, 1, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->f_max_time, NULL, src, + src_len - byte_counter, 1, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_8_bit_field(¶ms->tcp_space, NULL, src, + src_len - byte_counter, 3, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ + rc = decode_pcomp_16_bit_field(¶ms->non_tcp_space, NULL, src, + src_len - byte_counter, 3, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode ROHC parameter field (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ +static int decode_pcomp_rohc_params(struct gprs_sndcp_pcomp_rohc_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + int i; + + /* Mark all optional parameters invalid by default */ + params->max_cid = -1; + params->max_header = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_cid, NULL, src, + src_len - byte_counter, 0, 16383); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + rc = decode_pcomp_16_bit_field(¶ms->max_header, NULL, src, + src_len - byte_counter, 60, 255); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ + for (i = 0; i < 16; i++) { + params->profile_len = 0; + rc = decode_pcomp_16_bit_field(NULL, ¶ms->profile[i], src, + src_len - byte_counter, 0, + 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + params->profile_len = i + 1; + } + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V.42bis parameter field + * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ +static int decode_dcomp_v42bis_params(struct gprs_sndcp_dcomp_v42bis_params + *params, const uint8_t *src, + unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->p0 = -1; + params->p1 = -1; + params->p2 = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_16_bit_field(¶ms->p1, NULL, src, + src_len - byte_counter, 512, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ + rc = decode_pcomp_8_bit_field(¶ms->p2, NULL, src, + src_len - byte_counter, 6, 250); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Decode V44 parameter field (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ +static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params, + const uint8_t *src, unsigned int src_len) +{ + int rc; + int byte_counter = 0; + + /* Mark all optional parameters invalid by default */ + params->c0 = -1; + params->p0 = -1; + params->p1t = -1; + params->p1r = -1; + params->p3t = -1; + params->p3r = -1; + + /* Decode applicable SAPIs */ + rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, + src, src_len); + if (rc > 0) { + byte_counter += rc; + src += rc; + } else + return byte_counter; + + /* Decode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->c0, NULL, src, + src_len - byte_counter, 0, 255); + if (rc <= 0) + return byte_counter; + if ((params->c0 != 0x80) && (params->c0 != 0xC0)) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, + src_len - byte_counter, 0, 3); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p1r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + byte_counter += rc; + src += rc; + + /* Decode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3t, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3t < 2 * params->p1t) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Decode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ + rc = decode_pcomp_16_bit_field(¶ms->p3r, NULL, src, + src_len - byte_counter, 265, 65535); + if (rc <= 0) + return byte_counter; + if (params->p3r < 2 * params->p1r) + return -EINVAL; + byte_counter += rc; + src += rc; + + /* Return consumed length */ + return byte_counter; +} + +/* Lookup algorithm identfier by entity ID */ +static int lookup_algorithm_identifier(int entity, const struct + entity_algo_table + *lt, unsigned int lt_len, int compclass) +{ + int i; + + if (!lt) + return -1; + + for (i = 0; i < lt_len; i++) { + if ((lt[i].entity == entity) + && (lt[i].compclass == compclass)) + return lt[i].algo; + } + + return -1; +} + +/* Helper function for decode_comp_field(), decodes + * numeric pcomp/dcomp values */ +static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int compclass) +{ + int src_counter = 0; + int i; + + if (comp_field->p) { + /* Determine the number of expected PCOMP/DCOMP values */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + /* For protocol compression */ + switch (comp_field->algo) { + case RFC_1144: + comp_field->comp_len = RFC1144_PCOMP_NUM; + break; + case RFC_2507: + comp_field->comp_len = RFC2507_PCOMP_NUM; + break; + case ROHC: + comp_field->comp_len = ROHC_PCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } else { + /* For data compression */ + switch (comp_field->algo) { + case V42BIS: + comp_field->comp_len = V42BIS_DCOMP_NUM; + break; + case V44: + comp_field->comp_len = V44_DCOMP_NUM; + break; + + /* Exit if the algorithem type encodes + something unknown / unspecified */ + default: + return -EINVAL; + } + } + + for (i = 0; i < comp_field->comp_len; i++) { + if (i & 1) { + comp_field->comp[i] = (*src) & 0x0F; + src++; + src_counter++; + } else + comp_field->comp[i] = ((*src) >> 4) & 0x0F; + } + + if (i & 1) { + src++; + src_counter++; + } + } + + return src_counter; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are protocol compression specific */ +static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case RFC_1144: + comp_field->rfc1144_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc1144_params); + rc = decode_pcomp_rfc1144_params(comp_field->rfc1144_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case RFC_2507: + comp_field->rfc2507_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rfc2507_params); + rc = decode_pcomp_rfc2507_params(comp_field->rfc2507_params, + src, src_len); + if (rc < 0) + talloc_free(comp_field->rfc1144_params); + break; + case ROHC: + comp_field->rohc_params = talloc_zero(comp_field, struct + gprs_sndcp_pcomp_rohc_params); + rc = decode_pcomp_rohc_params(comp_field->rohc_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->rohc_params); + break; + + /* If no suitable decoder is detected, + leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->rfc1144_params = NULL; + comp_field->rfc2507_params = NULL; + comp_field->rohc_params = NULL; + } + + return rc; +} + +/* Helper function for decode_comp_field(), decodes the parameters + * which are data compression specific */ +static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, int src_len) +{ + int rc; + + switch (comp_field->algo) { + case V42BIS: + comp_field->v42bis_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v42bis_params); + rc = decode_dcomp_v42bis_params(comp_field->v42bis_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v42bis_params); + break; + case V44: + comp_field->v44_params = talloc_zero(comp_field, struct + gprs_sndcp_dcomp_v44_params); + rc = decode_dcomp_v44_params(comp_field->v44_params, src, + src_len); + if (rc < 0) + talloc_free(comp_field->v44_params); + break; + + /* If no suitable decoder is detected, + * leave the remaining bytes undecoded */ + default: + rc = src_len; + } + + if (rc < 0) { + comp_field->v42bis_params = NULL; + comp_field->v44_params = NULL; + } + + return rc; +} + +/* Decode data or protocol control information compression field + * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and + * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ +static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field, + const uint8_t *src, unsigned int src_len, + const struct entity_algo_table *lt, + unsigned int lt_len, int compclass) +{ + int src_counter = 0; + unsigned int len; + int rc; + + OSMO_ASSERT(comp_field); + + /* Exit immediately if it is clear that no + parseable data is present */ + if (src_len < 1 || !src) + return -EINVAL; + + /* Zero out target struct */ + memset(comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Decode Propose bit and Entity number */ + if ((*src) & 0x80) + comp_field->p = 1; + comp_field->entity = (*src) & 0x1F; + src_counter++; + src++; + + /* Decode algorithm number (if present) */ + if (comp_field->p) { + comp_field->algo = (*src) & 0x1F; + src_counter++; + src++; + } + /* Alternatively take the information from the lookup table */ + else + comp_field->algo = + lookup_algorithm_identifier(comp_field->entity, lt, + lt_len, compclass); + + /* Decode length field */ + len = *src; + src_counter++; + src++; + + /* Decode PCOMP/DCOMP values */ + rc = decode_comp_values(comp_field, src, compclass); + if (rc < 0) + return -EINVAL; + src_counter += rc; + src += rc; + len -= rc; + + /* Decode algorithm specific payload data */ + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) + rc = decode_pcomp_params(comp_field, src, len); + else if (compclass == SNDCP_XID_DATA_COMPRESSION) + rc = decode_dcomp_params(comp_field, src, len); + else + return -EINVAL; + + if (rc >= 0) + src_counter += rc; + else + return -EINVAL; + + /* Return consumed length */ + return src_counter; +} + +/* Helper function for gprs_sndcp_decode_xid() to decode XID blocks */ +static int decode_xid_block(struct llist_head *comp_fields, uint8_t tag, + uint16_t tag_len, const uint8_t *val, + const struct entity_algo_table *lt, + unsigned int lt_len) +{ + struct gprs_sndcp_comp_field *comp_field; + int byte_counter = 0; + int comp_field_count = 0; + int rc; + + byte_counter = 0; + do { + /* Bail if more than the maximum number of + comp_fields is generated */ + if (comp_field_count > MAX_ENTITIES * 2) { + return -EINVAL; + } + + /* Parse and add comp_field */ + comp_field = + talloc_zero(comp_fields, struct gprs_sndcp_comp_field); + + rc = decode_comp_field(comp_field, val + byte_counter, + tag_len - byte_counter, lt, lt_len, tag); + + if (rc < 0) { + talloc_free(comp_field); + return -EINVAL; + } + + byte_counter += rc; + llist_add(&comp_field->list, comp_fields); + comp_field_count++; + } + while (tag_len - byte_counter > 0); + + return byte_counter; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +static int gprs_sndcp_decode_xid(struct llist_head *comp_fields, + const uint8_t *src, unsigned int src_len, + const struct + entity_algo_table + *lt, unsigned int lt_len) +{ + int src_pos = 0; + uint8_t tag; + uint16_t tag_len; + const uint8_t *val; + int byte_counter = 0; + int rc; + int tlv_count = 0; + + /* Valid TLV-Tag and types */ + static const struct tlv_definition sndcp_xid_def = { + .def = { + [SNDCP_XID_VERSION_NUMBER] = {TLV_TYPE_TLV,}, + [SNDCP_XID_DATA_COMPRESSION] = {TLV_TYPE_TLV,}, + [SNDCP_XID_PROTOCOL_COMPRESSION] = {TLV_TYPE_TLV,}, + }, + }; + + /* Parse TLV-Encoded SNDCP-XID message and defer payload + to the apporpiate sub-parser functions */ + while (1) { + + /* Bail if an the maximum number of TLV fields + * have been parsed */ + if (tlv_count >= 3) { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Parse TLV field */ + rc = tlv_parse_one(&tag, &tag_len, &val, &sndcp_xid_def, + src + src_pos, src_len - src_pos); + if (rc > 0) + src_pos += rc; + else { + talloc_free(comp_fields); + return -EINVAL; + } + + /* Decode compression parameters */ + if ((tag == SNDCP_XID_PROTOCOL_COMPRESSION) + || (tag == SNDCP_XID_DATA_COMPRESSION)) { + rc = decode_xid_block(comp_fields, tag, tag_len, val, + lt, lt_len); + + if (rc < 0) { + talloc_free(comp_fields); + return -EINVAL; + } else + byte_counter += rc; + } + + /* Stop when no further TLV elements can be expected */ + if (src_len - src_pos <= 2) + break; + + tlv_count++; + } + + return 0; +} + +/* Fill up lookutable from a list with comression entitiy fields */ +static int gprs_sndcp_fill_table(struct + entity_algo_table *lt, + unsigned int lt_len, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field; + int i = 0; + + if (!comp_fields) + return -EINVAL; + if (!lt) + return -EINVAL; + + memset(lt, 0, lt_len * sizeof(lt)); + + llist_for_each_entry(comp_field, comp_fields, list) { + + lt[i].entity = comp_field->entity; + lt[i].algo = comp_field->algo; + lt[i].compclass = gprs_sndcp_get_compression_class(comp_field); + + if (lt[i].compclass < 0) { + memset(lt, 0, lt_len * sizeof(lt)); + return -EINVAL; + } + + i++; + } + + return i; +} + +/* Complete comp field params + * (if a param (dst) is not valid, it will be copied from source (src) */ +static int complete_comp_field_params(struct gprs_sndcp_comp_field + *comp_field_dst, const struct + gprs_sndcp_comp_field *comp_field_src) +{ + if (comp_field_dst->algo < 0) + return -EINVAL; + + if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) { + if (comp_field_dst->rfc1144_params->s01 < 0) { + comp_field_dst->rfc1144_params->s01 = + comp_field_src->rfc1144_params->s01; + } + return 0; + } + + if (comp_field_dst->rfc2507_params && comp_field_src->rfc2507_params) { + + if (comp_field_dst->rfc2507_params->f_max_period < 0) { + comp_field_dst->rfc2507_params->f_max_period = + comp_field_src->rfc2507_params->f_max_period; + } + if (comp_field_dst->rfc2507_params->f_max_time < 0) { + comp_field_dst->rfc2507_params->f_max_time = + comp_field_src->rfc2507_params->f_max_time; + } + if (comp_field_dst->rfc2507_params->max_header < 0) { + comp_field_dst->rfc2507_params->max_header = + comp_field_src->rfc2507_params->max_header; + } + if (comp_field_dst->rfc2507_params->tcp_space < 0) { + comp_field_dst->rfc2507_params->tcp_space = + comp_field_src->rfc2507_params->tcp_space; + } + if (comp_field_dst->rfc2507_params->non_tcp_space < 0) { + comp_field_dst->rfc2507_params->non_tcp_space = + comp_field_src->rfc2507_params->non_tcp_space; + } + return 0; + } + + if (comp_field_dst->rohc_params && comp_field_src->rohc_params) { + if (comp_field_dst->rohc_params->max_cid < 0) { + comp_field_dst->rohc_params->max_cid = + comp_field_src->rohc_params->max_cid; + } + if (comp_field_dst->rohc_params->max_header < 0) { + comp_field_dst->rohc_params->max_header = + comp_field_src->rohc_params->max_header; + } + if (comp_field_dst->rohc_params->profile_len > 0) { + memcpy(comp_field_dst->rohc_params->profile, + comp_field_src->rohc_params->profile, + sizeof(comp_field_dst->rohc_params->profile)); + comp_field_dst->rohc_params->profile_len = + comp_field_src->rohc_params->profile_len; + } + + return 0; + } + + if (comp_field_dst->v42bis_params && comp_field_src->v42bis_params) { + if (comp_field_dst->v42bis_params->p0 < 0) { + comp_field_dst->v42bis_params->p0 = + comp_field_src->v42bis_params->p0; + } + if (comp_field_dst->v42bis_params->p1 < 0) { + comp_field_dst->v42bis_params->p1 = + comp_field_src->v42bis_params->p1; + } + if (comp_field_dst->v42bis_params->p2 < 0) { + comp_field_dst->v42bis_params->p2 = + comp_field_src->v42bis_params->p2; + } + return 0; + } + + if (comp_field_dst->v44_params && comp_field_src->v44_params) { + if (comp_field_dst->v44_params->c0 < 0) { + comp_field_dst->v44_params->c0 = + comp_field_src->v44_params->c0; + } + if (comp_field_dst->v44_params->p0 < 0) { + comp_field_dst->v44_params->p0 = + comp_field_src->v44_params->p0; + } + if (comp_field_dst->v44_params->p1t < 0) { + comp_field_dst->v44_params->p1t = + comp_field_src->v44_params->p1t; + } + if (comp_field_dst->v44_params->p1r < 0) { + comp_field_dst->v44_params->p1r = + comp_field_src->v44_params->p1r; + } + if (comp_field_dst->v44_params->p3t < 0) { + comp_field_dst->v44_params->p3t = + comp_field_src->v44_params->p3t; + } + if (comp_field_dst->v44_params->p3r < 0) { + comp_field_dst->v44_params->p3r = + comp_field_src->v44_params->p3r; + } + return 0; + } + + /* There should be at least exist one param set + * in the destination struct, otherwise something + * must be wrong! */ + return -EINVAL; +} + +/* Complete missing parameters in a comp_field */ +static int gprs_sndcp_complete_comp_field(struct gprs_sndcp_comp_field + *comp_field, const struct llist_head + *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_src; + int rc = 0; + + llist_for_each_entry(comp_field_src, comp_fields, list) { + if (comp_field_src->entity == comp_field->entity) { + + /* Complete header fields */ + if (comp_field_src->comp_len > 0) { + memcpy(comp_field->comp, + comp_field_src->comp, + sizeof(comp_field_src->comp)); + comp_field->comp_len = comp_field_src->comp_len; + } + + /* Complete parameter fields */ + rc = complete_comp_field_params(comp_field, + comp_field_src); + } + } + + return rc; +} + +/* Complete missing parameters of all comp_field in a list */ +static int gprs_sndcp_complete_comp_fields(struct llist_head + *comp_fields_incomplete, + const struct llist_head *comp_fields) +{ + struct gprs_sndcp_comp_field *comp_field_incomplete; + int rc; + + llist_for_each_entry(comp_field_incomplete, comp_fields_incomplete, + list) { + + rc = gprs_sndcp_complete_comp_field(comp_field_incomplete, + comp_fields); + if (rc < 0) + return -EINVAL; + + } + + return 0; +} + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(const void *ctx, + const uint8_t *src, + unsigned int src_len, + const struct llist_head + *comp_fields_req) +{ + int rc; + int lt_len; + struct llist_head *comp_fields; + struct entity_algo_table lt[MAX_ENTITIES * 2]; + + OSMO_ASSERT(src); + + comp_fields = talloc_zero(ctx, struct llist_head); + INIT_LLIST_HEAD(comp_fields); + + if (comp_fields_req) { + /* Generate lookup table */ + lt_len = + gprs_sndcp_fill_table(lt, MAX_ENTITIES * 2, + comp_fields_req); + if (lt_len < 0) { + talloc_free(comp_fields); + return NULL; + } + + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, lt, + lt_len); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + rc = gprs_sndcp_complete_comp_fields(comp_fields, + comp_fields_req); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + + } else { + /* Parse SNDCP-CID XID-Field */ + rc = gprs_sndcp_decode_xid(comp_fields, src, src_len, NULL, 0); + if (rc < 0) { + talloc_free(comp_fields); + return NULL; + } + } + + return comp_fields; +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * dumps protocol compression parameters */ +static void dump_pcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case RFC_1144: + if (comp_field->rfc1144_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc1144_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc1144_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc1144_params->nsapi_len); + if (comp_field->rfc1144_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc1144_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc1144_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " s01=%d;\n", + comp_field->rfc1144_params->s01); + LOGP(DSNDCP, logl, " }\n"); + break; + case RFC_2507: + if (comp_field->rfc2507_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rfc2507_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc2507_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rfc2507_params->nsapi_len); + if (comp_field->rfc2507_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rfc2507_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rfc2507_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " f_max_period=%d;\n", + comp_field->rfc2507_params->f_max_period); + LOGP(DSNDCP, logl, + " f_max_time=%d;\n", + comp_field->rfc2507_params->f_max_time); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rfc2507_params->max_header); + LOGP(DSNDCP, logl, + " tcp_space=%d;\n", + comp_field->rfc2507_params->tcp_space); + LOGP(DSNDCP, logl, + " non_tcp_space=%d;\n", + comp_field->rfc2507_params->non_tcp_space); + LOGP(DSNDCP, logl, " }\n"); + break; + case ROHC: + if (comp_field->rohc_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_pcomp_rohc_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rohc_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->rohc_params->nsapi_len); + if (comp_field->rohc_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->rohc_params->nsapi[i]); + } + LOGP(DSNDCP, logl, + " max_cid=%d;\n", comp_field->rohc_params->max_cid); + LOGP(DSNDCP, logl, + " max_header=%d;\n", + comp_field->rohc_params->max_header); + LOGP(DSNDCP, logl, + " profile_len=%d;\n", + comp_field->rohc_params->profile_len); + if (comp_field->rohc_params->profile_len == 0) + LOGP(DSNDCP, logl, " profile[] = NULL;\n"); + for (i = 0; i < comp_field->rohc_params->profile_len; i++) + LOGP(DSNDCP, logl, + " profile[%d]=%04x;\n", + i, comp_field->rohc_params->profile[i]); + LOGP(DSNDCP, logl, " }\n"); + break; + } + +} + +/* Helper for gprs_sndcp_dump_comp_fields(), + * data protocol compression parameters */ +static void dump_dcomp_params(const struct gprs_sndcp_comp_field + *comp_field, unsigned int logl) +{ + int i; + + switch (comp_field->algo) { + case V42BIS: + if (comp_field->v42bis_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v42bis_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v42bis_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v42bis_params->nsapi_len); + if (comp_field->v42bis_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v42bis_params->nsapi_len; i++) + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v42bis_params->nsapi[i]); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v42bis_params->p0); + LOGP(DSNDCP, logl, " p1=%d;\n", + comp_field->v42bis_params->p1); + LOGP(DSNDCP, logl, " p2=%d;\n", + comp_field->v42bis_params->p2); + LOGP(DSNDCP, logl, " }\n"); + break; + case V44: + if (comp_field->v44_params == NULL) { + LOGP(DSNDCP, logl, + " gprs_sndcp_dcomp_v44_params=NULL\n"); + break; + } + LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v44_params {\n"); + LOGP(DSNDCP, logl, + " nsapi_len=%d;\n", + comp_field->v44_params->nsapi_len); + if (comp_field->v44_params->nsapi_len == 0) + LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); + for (i = 0; i < comp_field->v44_params->nsapi_len; i++) { + LOGP(DSNDCP, logl, + " nsapi[%d]=%d;\n", i, + comp_field->v44_params->nsapi[i]); + } + LOGP(DSNDCP, logl, " c0=%d;\n", + comp_field->v44_params->c0); + LOGP(DSNDCP, logl, " p0=%d;\n", + comp_field->v44_params->p0); + LOGP(DSNDCP, logl, " p1t=%d;\n", + comp_field->v44_params->p1t); + LOGP(DSNDCP, logl, " p1r=%d;\n", + comp_field->v44_params->p1r); + LOGP(DSNDCP, logl, " p3t=%d;\n", + comp_field->v44_params->p3t); + LOGP(DSNDCP, logl, " p3r=%d;\n", + comp_field->v44_params->p3r); + LOGP(DSNDCP, logl, " }\n"); + break; + } +} + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl) +{ + struct gprs_sndcp_comp_field *comp_field; + int i; + int compclass; + + OSMO_ASSERT(comp_fields); + + llist_for_each_entry(comp_field, comp_fields, list) { + LOGP(DSNDCP, logl, "SNDCP-XID:\n"); + LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n"); + LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity); + LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo); + LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len); + if (comp_field->comp_len == 0) + LOGP(DSNDCP, logl, " comp[] = NULL;\n"); + for (i = 0; i < comp_field->comp_len; i++) { + LOGP(DSNDCP, logl, " comp[%d]=%d;\n", i, + comp_field->comp[i]); + } + + compclass = gprs_sndcp_get_compression_class(comp_field); + + if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { + dump_pcomp_params(comp_field, logl); + } else if (compclass == SNDCP_XID_DATA_COMPRESSION) { + dump_dcomp_params(comp_field, logl); + } + + LOGP(DSNDCP, logl, "}\n"); + } + +} diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 7396c52..7b145f7 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -10,7 +10,9 @@ subscr \ mm_auth \ xid \ + sndcp_xid \ $(NULL) + if BUILD_NAT SUBDIRS += \ bsc-nat \ diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index d148c48..cf88101 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -56,7 +56,8 @@ $(top_builddir)/src/gprs/gprs_gb_parse.o \ $(top_builddir)/src/gprs/oap.o \ $(top_builddir)/src/gprs/oap_messages.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_llc_xid.o \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCORE_LIBS) \ @@ -66,7 +67,9 @@ $(LIBCRYPTO_LIBS) \ $(LIBGTP_LIBS) \ -lrt \ + -lm \ $(NULL) + if BUILD_IU sgsn_test_LDADD += \ $(top_builddir)/src/libiu/libiu.a \ diff --git a/openbsc/tests/sndcp_xid/Makefile.am b/openbsc/tests/sndcp_xid/Makefile.am new file mode 100644 index 0000000..99b9d1a --- /dev/null +++ b/openbsc/tests/sndcp_xid/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) + +EXTRA_DIST = sndcp_xid_test.ok + +noinst_PROGRAMS = sndcp_xid_test + +sndcp_xid_test_SOURCES = sndcp_xid_test.c + +sndcp_xid_test_LDADD = \ + $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBCRYPTO_LIBS) \ + -lgtp -lrt -lm + + diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.c b/openbsc/tests/sndcp_xid/sndcp_xid_test.c new file mode 100644 index 0000000..3a33619 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.c @@ -0,0 +1,282 @@ +/* Test SNDCP-XID Encoding/Decoding */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#include +#include + +#include +#include + +#include + +#include +#include + +/* Test SNDCP-XID decoding with a real world sample */ +static void test_xid_decode_realworld(const void *ctx) +{ + struct llist_head *comp_fields; + int rc; + printf("Testing SNDCP XID-Decoder/Encoder (real world data)\n"); + + /* Example of a real world SNDCP-XID message */ + uint8_t xid[] = + { 0x00, 0x01, 0x00, 0x02, 0x31, 0x82, 0x02, 0x27, 0x89, 0xff, 0xe0, + 0x00, 0x0f, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, + 0x01, 0x02, 0x00, 0x03, 0x01, 0x03, 0x00, 0x04, 0x01, 0x04, 0x00, 0x05, + 0x01, 0x05, 0x00, 0x06, 0x00, 0x07, 0x01, 0x07, 0x00, 0x08, 0x01, 0x08, + 0x80, 0x00, 0x04, 0x12, 0x00, 0x40, 0x07 }; + uint8_t xid_r[512]; + + /* Parse and show contained comp fields */ + comp_fields = gprs_sndcp_parse_xid(ctx, xid, sizeof(xid), NULL); + OSMO_ASSERT(comp_fields); + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields, DSNDCP); + + /* Encode comp-fields again */ + rc = gprs_sndcp_compile_xid(xid_r,sizeof(xid_r), comp_fields); + printf("Result length=%i\n",rc); + printf("Encoded: %s\n", osmo_hexdump_nospc(xid, sizeof(xid))); + printf("Rencoded: %s\n", osmo_hexdump_nospc(xid_r, rc)); + + OSMO_ASSERT(rc == 54); + OSMO_ASSERT(memcmp(xid, xid_r, sizeof(xid)) == 0); + + /* Free comp fields */ + talloc_free(comp_fields); + + printf("\n"); +} + +/* Encode and decode test with artificial test data */ +static void test_xid_encode_decode(const void *ctx) +{ + printf("Testing SNDCP XID-Encoder/Decoder\n"); + + LLIST_HEAD(comp_fields); + struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; + struct gprs_sndcp_comp_field rfc1144_comp_field; + struct gprs_sndcp_pcomp_rfc2507_params rfc2507_params; + struct gprs_sndcp_comp_field rfc2507_comp_field; + struct gprs_sndcp_pcomp_rohc_params rohc_params; + struct gprs_sndcp_comp_field rohc_comp_field; + struct gprs_sndcp_dcomp_v42bis_params v42bis_params; + struct gprs_sndcp_comp_field v42bis_comp_field; + struct gprs_sndcp_dcomp_v44_params v44_params; + struct gprs_sndcp_comp_field v44_comp_field; + struct llist_head *comp_fields_dec; + + uint8_t xid[512]; + unsigned int xid_len = sizeof(xid); + int rc; + + memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rfc2507_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&rohc_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + memset(&v44_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc1144_params.nsapi[0] = 5; + rfc1144_params.nsapi_len = 1; + + /* Setup rfc1144 operating parameters */ + rfc1144_params.s01 = 7; + + /* Setup rfc1144 compression field */ + rfc1144_comp_field.p = 1; + rfc1144_comp_field.entity = 0; + rfc1144_comp_field.algo = RFC_1144; + rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; + rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; + rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; + rfc1144_comp_field.rfc1144_params = &rfc1144_params; + + /* Setup which NSAPIs shall make use of rfc1144 */ + rfc2507_params.nsapi[0] = 6; + rfc2507_params.nsapi_len = 1; + + /* Setup rfc2507 operating parameters */ + rfc2507_params.f_max_period = 256; + rfc2507_params.f_max_time = 5; + rfc2507_params.max_header = 168; + rfc2507_params.tcp_space = 15; + rfc2507_params.non_tcp_space = 15; + + /* Setup rfc2507 compression field */ + rfc2507_comp_field.p = 1; + rfc2507_comp_field.entity = 1; + rfc2507_comp_field.algo = RFC_2507; + rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3; + rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4; + rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5; + rfc2507_comp_field.comp[RFC2507_PCOMP4] = 6; + rfc2507_comp_field.comp[RFC2507_PCOMP5] = 7; + rfc2507_comp_field.comp_len = RFC2507_PCOMP_NUM; + rfc2507_comp_field.rfc2507_params = &rfc2507_params; + + /* Setup which NSAPIs shall make use of ROHC */ + rohc_params.nsapi[0] = 5; + rohc_params.nsapi[1] = 6; + rohc_params.nsapi[2] = 7; + rohc_params.nsapi[3] = 8; + rohc_params.nsapi[4] = 9; + rohc_params.nsapi[5] = 10; + rohc_params.nsapi[6] = 11; + rohc_params.nsapi[7] = 12; + rohc_params.nsapi[8] = 13; + rohc_params.nsapi[9] = 14; + rohc_params.nsapi[10] = 15; + rohc_params.nsapi_len = 11; + + /* Setup ROHC operating parameters */ + rohc_params.max_cid = 15; /* default */ + rohc_params.max_header = 168; /* default */ + rohc_params.profile[0] = ROHC_UNCOMPRESSED; + rohc_params.profile[1] = ROHC_RTP; + rohc_params.profile[2] = ROHCV2_RTP; + rohc_params.profile[3] = ROHC_UDP; + rohc_params.profile[4] = ROHCv2_UDP; + rohc_params.profile[5] = ROHC_ESP; + rohc_params.profile[6] = ROHCV2_ESP; + rohc_params.profile[7] = ROHC_IP; + rohc_params.profile[8] = ROHCV2_IP; + rohc_params.profile[9] = ROHC_LLA; + rohc_params.profile[10] = ROHC_LLA_WITH_R_MODE; + rohc_params.profile[11] = ROHC_TCP; + rohc_params.profile[12] = ROHC_RTP_UDP_LITE; + rohc_params.profile[13] = ROHCV2_RTP_UDP_LITE; + rohc_params.profile[14] = ROHC_UDP_LITE; + rohc_params.profile[15] = ROHCV2_UDP_LITE; + rohc_params.profile_len = 16; + + /* Setup ROHC compression field */ + rohc_comp_field.p = 1; + rohc_comp_field.entity = 2; + rohc_comp_field.algo = ROHC; + rohc_comp_field.comp[ROHC_PCOMP1] = 8; + rohc_comp_field.comp[ROHC_PCOMP2] = 9; + rohc_comp_field.comp_len = ROHC_PCOMP_NUM; + rohc_comp_field.rohc_params = &rohc_params; + + /* Setup which NSAPIs shall make use of v42bis */ + v42bis_params.nsapi[0] = 5; + v42bis_params.nsapi_len = 1; + + /* Setup v42bis operating parameters */ + v42bis_params.p0 = 3; + v42bis_params.p1 = 2048; + v42bis_params.p2 = 20; + + /* Setup v42bis compression field */ + v42bis_comp_field.p = 1; + v42bis_comp_field.entity = 3; + v42bis_comp_field.algo = V42BIS; + v42bis_comp_field.comp[V42BIS_DCOMP1] = 10; + v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; + v42bis_comp_field.v42bis_params = &v42bis_params; + + /* Setup which NSAPIs shall make use of v44 */ + v44_params.nsapi[0] = 5; + v44_params.nsapi_len = 1; + + /* Setup v44 operating parameters */ + v44_params.c0 = 0x80; + v44_params.p0 = 3; + v44_params.p1t = 300; + v44_params.p1r = 300; + v44_params.p3t = 600; + v44_params.p3r = 600; + + /* Setup v44 compression field */ + v44_comp_field.p = 1; + v44_comp_field.entity = 3; + v44_comp_field.algo = V44; + v44_comp_field.comp[V44_DCOMP1] = 10; + v44_comp_field.comp[V44_DCOMP2] = 11; + v44_comp_field.comp_len = V44_DCOMP_NUM; + v44_comp_field.v44_params = &v44_params; + + /* Add compression field(s) to list */ + llist_add(&v44_comp_field.list, &comp_fields); + llist_add(&v42bis_comp_field.list, &comp_fields); + llist_add(&rfc1144_comp_field.list, &comp_fields); + llist_add(&rfc2507_comp_field.list, &comp_fields); + llist_add(&rohc_comp_field.list, &comp_fields); + printf("Test input data:\n"); + gprs_sndcp_dump_comp_fields(&comp_fields, DSNDCP); + + /* Encode SNDCP-XID fields */ + rc = gprs_sndcp_compile_xid(xid, xid_len, &comp_fields); + OSMO_ASSERT(rc > 0); + + printf("Encoded: %s (%i bytes)\n", osmo_hexdump_nospc(xid, rc), rc); + + /* Parse and show contained comp fields */ + comp_fields_dec = gprs_sndcp_parse_xid(ctx, xid, rc, NULL); + OSMO_ASSERT(comp_fields_dec); + + printf("Decoded:\n"); + gprs_sndcp_dump_comp_fields(comp_fields_dec, DSNDCP); + + /* Free comp fields */ + talloc_free(comp_fields_dec); +} + +static struct log_info_cat gprs_categories[] = { + [DSNDCP] = { + .name = "DSNDCP", + .description = + "GPRS Sub-Network Dependent Control Protocol (SNDCP)", + .enabled = 1,.loglevel = LOGL_DEBUG, + } +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +int main(int argc, char **argv) +{ + void *xid_ctx; + + osmo_init_logging(&info); + + xid_ctx = talloc_named_const(NULL, 0, "xid_ctx"); + + test_xid_decode_realworld(xid_ctx); + test_xid_encode_decode(xid_ctx); + + printf("Done\n"); + + talloc_report_full(xid_ctx, stderr); + OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1); + return 0; +} + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +} diff --git a/openbsc/tests/sndcp_xid/sndcp_xid_test.ok b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok new file mode 100644 index 0000000..f357282 --- /dev/null +++ b/openbsc/tests/sndcp_xid/sndcp_xid_test.ok @@ -0,0 +1,11 @@ +Testing SNDCP XID-Decoder/Encoder (real world data) +Decoded: +Result length=54 +Encoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 +Rencoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 + +Testing SNDCP XID-Encoder/Decoder +Test input data: +Encoded: 000100011a83010dab00208003012c012c02580258830007a000200308001402408000041200200781010c3456700040010005a80f000f82022789ffe0000f00a80000000101010002010200030103000401040005010500060007010700080108 (97 bytes) +Decoded: +Done diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 6470ab9..85a81d6 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -129,3 +129,10 @@ cat $abs_srcdir/xid/xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([sndcp_xid]) +AT_KEYWORDS([sndcp_xid]) +cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) +AT_CLEANUP + -- To view, visit https://gerrit.osmocom.org/641 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If2d63fe2550864cafef3156b1dc0629037c49c1e Gerrit-PatchSet: 17 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:18:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:18:00 +0000 Subject: [MERGED] openbsc[master]: RFC1144: add slhc code from linux kernel In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: RFC1144: add slhc code from linux kernel ...................................................................... RFC1144: add slhc code from linux kernel SLHC is an Implementation of RFC1144 TCP/IP header compression. We will need RFC1144 compression to compress GPRS TCP/IP traffic. The implementation pushed with this commit was taken from: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git commit 29b4817d4018df78086157ea3a55c1d9424a7cfc Change-Id: Ied69c143678dc4a64cecc671f5c4dfebe19d8519 --- A openbsc/include/openbsc/slhc_vj.h A openbsc/src/gprs/slhc.c 2 files changed, 927 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/slhc_vj.h b/openbsc/include/openbsc/slhc_vj.h new file mode 100644 index 0000000..8716d59 --- /dev/null +++ b/openbsc/include/openbsc/slhc_vj.h @@ -0,0 +1,183 @@ +#ifndef _SLHC_H +#define _SLHC_H +/* + * Definitions for tcp compression routines. + * + * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van at helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens at ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation + * + * - Feb 1991 Bill_Simpson at um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowledgment, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + + +#include +#include + +/* SLIP compression masks for len/vers byte */ +#define SL_TYPE_IP 0x40 +#define SL_TYPE_UNCOMPRESSED_TCP 0x70 +#define SL_TYPE_COMPRESSED_TCP 0x80 +#define SL_TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + +/* + * data type and sizes conversion assumptions: + * + * VJ code KA9Q style generic + * u_char byte_t unsigned char 8 bits + * u_short int16 unsigned short 16 bits + * u_int int16 unsigned short 16 bits + * u_long unsigned long unsigned long 32 bits + * int int32 long 32 bits + */ + +typedef __u8 byte_t; +typedef __u32 int32; + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + byte_t cs_this; /* connection id number (xmit) */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; + unsigned char cs_ipopt[64]; + unsigned char cs_tcpopt[64]; + int cs_hsize; +}; +#define NULLSLSTATE (struct cstate *)0 + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct slcompress { + struct cstate *tstate; /* transmit connection states (array)*/ + struct cstate *rstate; /* receive connection states (array)*/ + + byte_t tslot_limit; /* highest transmit slot id (0-l)*/ + byte_t rslot_limit; /* highest receive slot id (0-l)*/ + + byte_t xmit_oldest; /* oldest xmit in ring */ + byte_t xmit_current; /* most recent xmit id */ + byte_t recv_current; /* most recent rcvd id */ + + byte_t flags; +#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ + + int32 sls_o_nontcp; /* outbound non-TCP packets */ + int32 sls_o_tcp; /* outbound TCP packets */ + int32 sls_o_uncompressed; /* outbound uncompressed packets */ + int32 sls_o_compressed; /* outbound compressed packets */ + int32 sls_o_searches; /* searches for connection state */ + int32 sls_o_misses; /* times couldn't find conn. state */ + + int32 sls_i_uncompressed; /* inbound uncompressed packets */ + int32 sls_i_compressed; /* inbound compressed packets */ + int32 sls_i_error; /* inbound error packets */ + int32 sls_i_tossed; /* inbound packets tossed because of error */ + + int32 sls_i_runt; + int32 sls_i_badcheck; +}; +#define NULLSLCOMPR (struct slcompress *)0 + +/* In slhc.c: */ +struct slcompress *slhc_init(int rslots, int tslots); +void slhc_free(struct slcompress *comp); + +int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid); +int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_toss(struct slcompress *comp); + +#endif /* _SLHC_H */ diff --git a/openbsc/src/gprs/slhc.c b/openbsc/src/gprs/slhc.c new file mode 100644 index 0000000..27ed252 --- /dev/null +++ b/openbsc/src/gprs/slhc.c @@ -0,0 +1,744 @@ +/* + * Routines to compress and uncompress tcp packets (for transmission + * over low speed serial lines). + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van at helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens at ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation (from 1.19) + * PPP.05 02-15-90 [ks] + * PPP.08 05-02-90 [ks] use PPP protocol field to signal compression + * PPP.15 09-90 [ks] improve mbuf handling + * PPP.16 11-02 [karn] substantially rewritten to use NOS facilities + * + * - Feb 1991 Bill_Simpson at um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + * - Jul 1994 Dmitry Gorodchanin + * Fixes for memory leaks. + * - Oct 1994 Dmitry Gorodchanin + * Modularization. + * - Jan 1995 Bjorn Ekwall + * Use ip_fast_csum from ip.h + * - July 1995 Christos A. Polyzols + * Spotted bug in tcp option checking + * + * + * This module is a difficult issue. It's clearly inet code but it's also clearly + * driver code belonging close to PPP and SLIP + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_INET +/* Entire module is for IP only */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned char *encode(unsigned char *cp, unsigned short n); +static long decode(unsigned char **cpp); +static unsigned char * put16(unsigned char *cp, unsigned short x); +static unsigned short pull16(unsigned char **cpp); + +/* Allocate compression data structure + * slots must be in range 0 to 255 (zero meaning no compression) + * Returns pointer to structure or ERR_PTR() on error. + */ +struct slcompress * +slhc_init(int rslots, int tslots) +{ + register short i; + register struct cstate *ts; + struct slcompress *comp; + + if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) + return ERR_PTR(-EINVAL); + + comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + if (! comp) + goto out_fail; + + if (rslots > 0) { + size_t rsize = rslots * sizeof(struct cstate); + comp->rstate = kzalloc(rsize, GFP_KERNEL); + if (! comp->rstate) + goto out_free; + comp->rslot_limit = rslots - 1; + } + + if (tslots > 0) { + size_t tsize = tslots * sizeof(struct cstate); + comp->tstate = kzalloc(tsize, GFP_KERNEL); + if (! comp->tstate) + goto out_free2; + comp->tslot_limit = tslots - 1; + } + + comp->xmit_oldest = 0; + comp->xmit_current = 255; + comp->recv_current = 255; + /* + * don't accept any packets with implicit index until we get + * one with an explicit index. Otherwise the uncompress code + * will try to use connection 255, which is almost certainly + * out of range + */ + comp->flags |= SLF_TOSS; + + if ( tslots > 0 ) { + ts = comp->tstate; + for(i = comp->tslot_limit; i > 0; --i){ + ts[i].cs_this = i; + ts[i].next = &(ts[i - 1]); + } + ts[0].next = &(ts[comp->tslot_limit]); + ts[0].cs_this = 0; + } + return comp; + +out_free2: + kfree(comp->rstate); +out_free: + kfree(comp); +out_fail: + return ERR_PTR(-ENOMEM); +} + + +/* Free a compression data structure */ +void +slhc_free(struct slcompress *comp) +{ + if ( comp == NULLSLCOMPR ) + return; + + if ( comp->tstate != NULLSLSTATE ) + kfree( comp->tstate ); + + if ( comp->rstate != NULLSLSTATE ) + kfree( comp->rstate ); + + kfree( comp ); +} + + +/* Put a short in host order into a char array in network order */ +static inline unsigned char * +put16(unsigned char *cp, unsigned short x) +{ + *cp++ = x >> 8; + *cp++ = x; + + return cp; +} + + +/* Encode a number */ +static unsigned char * +encode(unsigned char *cp, unsigned short n) +{ + if(n >= 256 || n == 0){ + *cp++ = 0; + cp = put16(cp,n); + } else { + *cp++ = n; + } + return cp; +} + +/* Pull a 16-bit integer in host order from buffer in network byte order */ +static unsigned short +pull16(unsigned char **cpp) +{ + short rval; + + rval = *(*cpp)++; + rval <<= 8; + rval |= *(*cpp)++; + return rval; +} + +/* Decode a number */ +static long +decode(unsigned char **cpp) +{ + register int x; + + x = *(*cpp)++; + if(x == 0){ + return pull16(cpp) & 0xffff; /* pull16 returns -1 on error */ + } else { + return x & 0xff; /* -1 if PULLCHAR returned error */ + } +} + +/* + * icp and isize are the original packet. + * ocp is a place to put a copy if necessary. + * cpp is initially a pointer to icp. If the copy is used, + * change it to ocp. + */ + +int +slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid) +{ + register struct cstate *ocs = &(comp->tstate[comp->xmit_oldest]); + register struct cstate *lcs = ocs; + register struct cstate *cs = lcs->next; + register unsigned long deltaS, deltaA; + register short changes = 0; + int hlen; + unsigned char new_seq[16]; + register unsigned char *cp = new_seq; + struct iphdr *ip; + struct tcphdr *th, *oth; + __sum16 csum; + + + /* + * Don't play with runt packets. + */ + + if(isizeprotocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { + /* Send as regular IP */ + if(ip->protocol != IPPROTO_TCP) + comp->sls_o_nontcp++; + else + comp->sls_o_tcp++; + return isize; + } + /* Extract TCP header */ + + th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); + hlen = ip->ihl*4 + th->doff*4; + + /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or + * some other control bit is set). Also uncompressible if + * it's a runt. + */ + if(hlen > isize || th->syn || th->fin || th->rst || + ! (th->ack)){ + /* TCP connection stuff; send as regular IP */ + comp->sls_o_tcp++; + return isize; + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way, + * we need to locate (or create) the connection state. + * + * States are kept in a circularly linked list with + * xmit_oldest pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + for ( ; ; ) { + if( ip->saddr == cs->cs_ip.saddr + && ip->daddr == cs->cs_ip.daddr + && th->source == cs->cs_tcp.source + && th->dest == cs->cs_tcp.dest) + goto found; + + /* if current equal oldest, at end of list */ + if ( cs == ocs ) + break; + lcs = cs; + cs = cs->next; + comp->sls_o_searches++; + } + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * xmit_oldest to update the lru linkage. + */ + comp->sls_o_misses++; + comp->xmit_oldest = lcs->cs_this; + goto uncompressed; + +found: + /* + * Found it -- move to the front on the connection list. + */ + if(lcs == ocs) { + /* found at most recently used */ + } else if (cs == ocs) { + /* found at least recently used */ + comp->xmit_oldest = lcs->cs_this; + } else { + /* more than 2 elements */ + lcs->next = cs->next; + cs->next = ocs->next; + ocs->next = cs; + } + + /* + * Make sure that only what we expect to change changed. + * Check the following: + * IP protocol version, header length & type of service. + * The "Don't fragment" bit. + * The time-to-live field. + * The TCP header length. + * IP options, if any. + * TCP options, if any. + * If any of these things are different between the previous & + * current datagram, we send the current datagram `uncompressed'. + */ + oth = &cs->cs_tcp; + + if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl + || ip->tos != cs->cs_ip.tos + || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) + || ip->ttl != cs->cs_ip.ttl + || th->doff != cs->cs_tcp.doff + || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) + || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if(th->urg){ + deltaS = ntohs(th->urg_ptr); + cp = encode(cp,deltaS); + changes |= NEW_U; + } else if(th->urg_ptr != oth->urg_ptr){ + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ + cp = encode(cp,deltaS); + changes |= NEW_W; + } + if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ + if(deltaA > 0x0000ffff) + goto uncompressed; + cp = encode(cp,deltaA); + changes |= NEW_A; + } + if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ + if(deltaS > 0x0000ffff) + goto uncompressed; + cp = encode(cp,deltaS); + changes |= NEW_S; + } + + switch(changes){ + case 0: /* Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if(ip->tot_len != cs->cs_ip.tot_len && + ntohs(cs->cs_ip.tot_len) == hlen) + break; + goto uncompressed; + case SPECIAL_I: + case SPECIAL_D: + /* actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + case NEW_S|NEW_A: + if(deltaS == deltaA && + deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + case NEW_S: + if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + } + deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); + if(deltaS != 1){ + cp = encode(cp,deltaS); + changes |= NEW_I; + } + if(th->psh) + changes |= TCP_PUSH_BIT; + /* Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + csum = th->check; + memcpy(&cs->cs_ip,ip,20); + memcpy(&cs->cs_tcp,th,20); + /* We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. + */ + deltaS = cp - new_seq; + if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ + cp = ocp; + *cpp = ocp; + *cp++ = changes | NEW_C; + *cp++ = cs->cs_this; + comp->xmit_current = cs->cs_this; + } else { + cp = ocp; + *cpp = ocp; + *cp++ = changes; + } + *(__sum16 *)cp = csum; + cp += 2; +/* deltaS is now the size of the change section of the compressed header */ + memcpy(cp,new_seq,deltaS); /* Write list of deltas */ + memcpy(cp+deltaS,icp+hlen,isize-hlen); + comp->sls_o_compressed++; + ocp[0] |= SL_TYPE_COMPRESSED_TCP; + return isize - hlen + deltaS + (cp - ocp); + + /* Update connection state cs & send uncompressed packet (i.e., + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + memcpy(&cs->cs_ip,ip,20); + memcpy(&cs->cs_tcp,th,20); + if (ip->ihl > 5) + memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4); + if (th->doff > 5) + memcpy(cs->cs_tcpopt, th+1, ((th->doff) - 5) * 4); + comp->xmit_current = cs->cs_this; + comp->sls_o_uncompressed++; + memcpy(ocp, icp, isize); + *cpp = ocp; + ocp[9] = cs->cs_this; + ocp[0] |= SL_TYPE_UNCOMPRESSED_TCP; + return isize; +} + + +int +slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) +{ + register int changes; + long x; + register struct tcphdr *thp; + register struct iphdr *ip; + register struct cstate *cs; + int len, hdrlen; + unsigned char *cp = icp; + + /* We've got a compressed packet; read the change byte */ + comp->sls_i_compressed++; + if(isize < 3){ + comp->sls_i_error++; + return 0; + } + changes = *cp++; + if(changes & NEW_C){ + /* Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + x = *cp++; /* Read conn index */ + if(x < 0 || x > comp->rslot_limit) + goto bad; + + comp->flags &=~ SLF_TOSS; + comp->recv_current = x; + } else { + /* this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. */ + if(comp->flags & SLF_TOSS){ + comp->sls_i_tossed++; + return 0; + } + } + cs = &comp->rstate[comp->recv_current]; + thp = &cs->cs_tcp; + ip = &cs->cs_ip; + + thp->check = *(__sum16 *)cp; + cp += 2; + + thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0; +/* + * we can use the same number for the length of the saved header and + * the current one, because the packet wouldn't have been sent + * as compressed unless the options were the same as the previous one + */ + + hdrlen = ip->ihl * 4 + thp->doff * 4; + + switch(changes & SPECIALS_MASK){ + case SPECIAL_I: /* Echoed terminal traffic */ + { + register short i; + i = ntohs(ip->tot_len) - hdrlen; + thp->ack_seq = htonl( ntohl(thp->ack_seq) + i); + thp->seq = htonl( ntohl(thp->seq) + i); + } + break; + + case SPECIAL_D: /* Unidirectional data */ + thp->seq = htonl( ntohl(thp->seq) + + ntohs(ip->tot_len) - hdrlen); + break; + + default: + if(changes & NEW_U){ + thp->urg = 1; + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->urg_ptr = htons(x); + } else + thp->urg = 0; + if(changes & NEW_W){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->window = htons( ntohs(thp->window) + x); + } + if(changes & NEW_A){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->ack_seq = htonl( ntohl(thp->ack_seq) + x); + } + if(changes & NEW_S){ + if((x = decode(&cp)) == -1) { + goto bad; + } + thp->seq = htonl( ntohl(thp->seq) + x); + } + break; + } + if(changes & NEW_I){ + if((x = decode(&cp)) == -1) { + goto bad; + } + ip->id = htons (ntohs (ip->id) + x); + } else + ip->id = htons (ntohs (ip->id) + 1); + + /* + * At this point, cp points to the first byte of data in the + * packet. Put the reconstructed TCP and IP headers back on the + * packet. Recalculate IP checksum (but not TCP checksum). + */ + + len = isize - (cp - icp); + if (len < 0) + goto bad; + len += hdrlen; + ip->tot_len = htons(len); + ip->check = 0; + + memmove(icp + hdrlen, cp, len - hdrlen); + + cp = icp; + memcpy(cp, ip, 20); + cp += 20; + + if (ip->ihl > 5) { + memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4); + cp += (ip->ihl - 5) * 4; + } + + put_unaligned(ip_fast_csum(icp, ip->ihl), + &((struct iphdr *)icp)->check); + + memcpy(cp, thp, 20); + cp += 20; + + if (thp->doff > 5) { + memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4); + cp += ((thp->doff) - 5) * 4; + } + + return len; +bad: + comp->sls_i_error++; + return slhc_toss( comp ); +} + + +int +slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +{ + register struct cstate *cs; + unsigned ihl; + + unsigned char index; + + if(isize < 20) { + /* The packet is shorter than a legal IP header */ + comp->sls_i_runt++; + return slhc_toss( comp ); + } + /* Peek at the IP header's IHL field to find its length */ + ihl = icp[0] & 0xf; + if(ihl < 20 / 4){ + /* The IP header length field is too small */ + comp->sls_i_runt++; + return slhc_toss( comp ); + } + index = icp[9]; + icp[9] = IPPROTO_TCP; + + if (ip_fast_csum(icp, ihl)) { + /* Bad IP header checksum; discard */ + comp->sls_i_badcheck++; + return slhc_toss( comp ); + } + if(index > comp->rslot_limit) { + comp->sls_i_error++; + return slhc_toss(comp); + } + + /* Update local state */ + cs = &comp->rstate[comp->recv_current = index]; + comp->flags &=~ SLF_TOSS; + memcpy(&cs->cs_ip,icp,20); + memcpy(&cs->cs_tcp,icp + ihl*4,20); + if (ihl > 5) + memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); + if (cs->cs_tcp.doff > 5) + memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); + cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; + /* Put headers back on packet + * Neither header checksum is recalculated + */ + comp->sls_i_uncompressed++; + return isize; +} + +int +slhc_toss(struct slcompress *comp) +{ + if ( comp == NULLSLCOMPR ) + return 0; + + comp->flags |= SLF_TOSS; + return 0; +} + +#else /* CONFIG_INET */ + +int +slhc_toss(struct slcompress *comp) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss"); + return -EINVAL; +} +int +slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress"); + return -EINVAL; +} +int +slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress"); + return -EINVAL; +} + +int +slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember"); + return -EINVAL; +} + +void +slhc_free(struct slcompress *comp) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free"); +} +struct slcompress * +slhc_init(int rslots, int tslots) +{ + printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init"); + return NULL; +} + +#endif /* CONFIG_INET */ + +/* VJ header compression */ +EXPORT_SYMBOL(slhc_init); +EXPORT_SYMBOL(slhc_free); +EXPORT_SYMBOL(slhc_remember); +EXPORT_SYMBOL(slhc_compress); +EXPORT_SYMBOL(slhc_uncompress); +EXPORT_SYMBOL(slhc_toss); + +MODULE_LICENSE("Dual BSD/GPL"); -- To view, visit https://gerrit.osmocom.org/634 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ied69c143678dc4a64cecc671f5c4dfebe19d8519 Gerrit-PatchSet: 17 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:20:40 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:20:40 +0000 Subject: libosmocore[master]: libosmocoding: migrate transcoding routines from OsmoBTS In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/933 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:20:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:20:56 +0000 Subject: osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Patch Set 10: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 10 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:21:27 +0000 Subject: [MERGED] osmo-bts[master]: octphy: Fixing missing payload type in ph. chan. activation In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: Fixing missing payload type in ph. chan. activation ...................................................................... octphy: Fixing missing payload type in ph. chan. activation in l1_oml.c:ts_connect() the payload type (ulPayloadType) was not configured to full-rate for PDTCHF PACCHF and PTCCHF. Older octasic firmwares (below octsdr-2g-02.06.00-B964-alpha) will tolerate this, newer versions will crash during channel initalitation. Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index ed365b6..7735261 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1448,6 +1448,7 @@ * a TCH/H ? */ switch (oc->ulChannelType) { case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_TCHF_FACCHF_SACCHTF: + case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_PDTCHF_PACCHF_PTCCHF: oc->ulPayloadType = cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_FULL_RATE; break; case cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_TCHH_FACCHH_SACCHTH: -- To view, visit https://gerrit.osmocom.org/900 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:25:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:25:49 +0000 Subject: [MERGED] libosmo-abis[master]: Use callback for polling data In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Use callback for polling data ...................................................................... Use callback for polling data Previously rs->rtp_bfd.when and rs->rtcp_bfd.when value of BSC_FD_READ was overridden by 0. Fix it. Reported by coverity: CID 1357763. Change-Id: I11940cbf50361c4ea262d7001a16f9a982392f27 --- M src/trau/osmo_ortp.c 1 file changed, 0 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index cc1d748..0bb1197 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -218,7 +218,6 @@ rs->rtp_bfd.fd = rtp_session_get_rtp_socket(rs->sess); rs->rtcp_bfd.fd = rtp_session_get_rtcp_socket(rs->sess); rs->rtp_bfd.when = rs->rtcp_bfd.when = BSC_FD_READ; - rs->rtp_bfd.when = rs->rtcp_bfd.when = 0; rs->rtp_bfd.data = rs->rtcp_bfd.data = rs; rs->rtp_bfd.cb = osmo_rtp_fd_cb; rs->rtcp_bfd.cb = osmo_rtcp_fd_cb; -- To view, visit https://gerrit.osmocom.org/864 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I11940cbf50361c4ea262d7001a16f9a982392f27 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:26:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:26:39 +0000 Subject: openbsc[master]: mscsplit: bsc_init: don't pass telnet dummy conn In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/920 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:27:25 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:27:25 +0000 Subject: openbsc[master]: mscsplit: move subscriber conns list into struct gsm_network In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/921 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:28:07 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:28:07 +0000 Subject: openbsc[master]: mscsplit: gsm_network_init(): add explicit root talloc ctx In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/922 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I92f6b47b1eeea2e8f3fba66f25d7e708e5659f8a Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:28:32 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:28:32 +0000 Subject: openbsc[master]: mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/923 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I168106599b788f586be0ff0af4699b9746c1b103 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:29:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:29:01 +0000 Subject: openbsc[master]: mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/924 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9e2c0d9c18d4cebb5efb71565ad84df2bc2e0251 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:29:15 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:29:15 +0000 Subject: openbsc[master]: mscsplit: abis vty: decouple from global bsc_gsmnet variable In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/925 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib65a18db06b8bc4fc7d56bf56dd64a52cc1cd253 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:29:37 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:29:37 +0000 Subject: openbsc[master]: mscsplit: add gsm_network backpointer to gsm_subscriber_conn... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/926 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If8870972f1b3e333c2a4cce97cdc95bdee0382a1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:30:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:30:28 +0000 Subject: openbsc[master]: mscsplit: directly access gsm_network backpointer from gsm_s... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/927 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I34537025986713291e14c8212a81539b497befd4 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:30:43 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:30:43 +0000 Subject: openbsc[master]: mscsplit: bsc_init: don't pass telnet dummy conn In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/920 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:36:08 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:36:08 +0000 Subject: [MERGED] osmo-bts[master]: octphy: Fixing band selection for ARFCN 0 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: Fixing band selection for ARFCN 0 ...................................................................... octphy: Fixing band selection for ARFCN 0 There is now an exception for ARFCN 0 in osmocom_to_octphy_band to distingush ARFCN 0 (E-GSM) and 1-124 (P-GSM). Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 3 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index d621bcf..c4105ac 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -98,7 +98,9 @@ case GSM_BAND_850: return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_850; case GSM_BAND_900: - if (arfcn >= 955 && arfcn <= 974) + if (arfcn == 0) + return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; + else if (arfcn >= 955 && arfcn <= 974) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_R_900; else if (arfcn >= 975 && arfcn <= 1023) return cOCTVC1_RADIO_STANDARD_FREQ_BAND_GSM_ENUM_E_900; -- To view, visit https://gerrit.osmocom.org/903 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:36:22 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:36:22 +0000 Subject: [MERGED] osmo-bts[master]: sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty ...................................................................... sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty Instead of passing the msgb ctx to telnet_init(), pass the *mgr* ctx. Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f --- M src/osmo-bts-litecell15/misc/lc15bts_mgr.c M src/osmo-bts-sysmo/misc/sysmobts_mgr.c 2 files changed, 2 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c index 506e525..c97525c 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c @@ -249,7 +249,7 @@ exit(1); } - rc = telnet_init(tall_msgb_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index fce375b..ccb84d8 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -274,7 +274,7 @@ exit(1); } - rc = telnet_init(tall_msgb_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); -- To view, visit https://gerrit.osmocom.org/848 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 03:37:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 03:37:52 +0000 Subject: [MERGED] libosmocore[master]: utils/conv_gen.py: code style changes (line width, tabs, etc.) In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: utils/conv_gen.py: code style changes (line width, tabs, etc.) ...................................................................... utils/conv_gen.py: code style changes (line width, tabs, etc.) Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 --- M utils/conv_gen.py 1 file changed, 233 insertions(+), 181 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/utils/conv_gen.py b/utils/conv_gen.py index bb547de..a4f918f 100644 --- a/utils/conv_gen.py +++ b/utils/conv_gen.py @@ -27,7 +27,8 @@ class ConvolutionalCode(object): - def __init__(self, block_len, polys, name = "call-me", description = "LOL", puncture = []): + def __init__(self, block_len, polys, name, + description = None, puncture = []): # Save simple params self.block_len = block_len self.k = 1 @@ -50,9 +51,14 @@ rp = [x[1] for x in self.polys if x[1] != 1] if rp: if not all([x == rp[0] for x in rp]): - raise ValueError("Bad polynoms: Can't have multiple different divider polynoms !") + raise ValueError("Bad polynoms: " + "Can't have multiple different divider polynoms!") + if not all([x[0] == 1 for x in polys if x[1] == 1]): - raise ValueError("Bad polynoms: Can't have a '1' divider with a non '1' dividend in a recursive code") + raise ValueError("Bad polynoms: " + "Can't have a '1' divider with a non '1' dividend " + "in a recursive code") + self.poly_divider = rp[0] @property @@ -85,7 +91,8 @@ rv = [] for p_n, p_d in self.polys: if self.recursive and p_d == 1: - o = bit # No choice ... (systematic output in recursive case) + # No choice ... (systematic output in recursive case) + o = bit else: o = combine(src, p_n, self.k) rv.append(o) @@ -121,32 +128,48 @@ nb = self.next_term_output(state, ns = ns) return ns, nb - def _print_term(self, fi, num_states, pack = False): + def _print_term(self, fi, num_states, pack = False): d = [] for state in range(num_states): - x = pack(self.next_term_output(state)) if pack else self.next_term_state(state) + if pack: + x = pack(self.next_term_output(state)) + else: + x = self.next_term_state(state) + d.append("%d, " % x) print >>fi, "\t%s" % ''.join(d) def _print_x(self, fi, num_states, pack = False): for state in range(num_states): - x0 = pack(self.next_output(state, 0)) if pack else self.next_state(state, 0) - x1 = pack(self.next_output(state, 1)) if pack else self.next_state(state, 1) + if pack: + x0 = pack(self.next_output(state, 0)) + x1 = pack(self.next_output(state, 1)) + else: + x0 = self.next_state(state, 0) + x1 = self.next_state(state, 1) + print >>fi, "\t{ %2d, %2d }," % (x0, x1) def gen_tables(self, pref, fi): - pack = lambda n: sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) + pack = lambda n: \ + sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)]) num_states = 1 << (self.k - 1) - print >>fi, "\nstatic const uint8_t %s_state[][2] = {" % self.name + + print >>fi, \ + "\nstatic const uint8_t %s_state[][2] = {" % self.name self._print_x(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name + print >>fi, \ + "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name self._print_x(fi, num_states, pack) print >>fi, "};" if self.recursive: - print >>fi, "\nstatic const uint8_t %s_term_state[] = {" % self.name + print >>fi, \ + "\nstatic const uint8_t %s_term_state[] = {" % self.name self._print_term(fi, num_states) - print >>fi, "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name + + print >>fi, \ + "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name self._print_term(fi, num_states, pack) print >>fi, "};" @@ -156,7 +179,14 @@ print >>fi, "\t%d," % p print >>fi, "};" - print >>fi, "\n/* %s */" % self.description + # Write description as a multi-line comment + if self.description is not None: + print >>fi, "\n/**" + for line in self.description: + print >>fi, " * %s" % line + print >>fi, " */" + + # Print a final convolutional code definition print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name) print >>fi, "\t.N = %d," % self.rate_inv print >>fi, "\t.K = %d," % self.k @@ -188,93 +218,102 @@ G7 = poly(0, 1, 2, 3, 6) CCH_poly = [ - ( G0, 1 ), - ( G1, 1 ) + ( G0, 1 ), + ( G1, 1 ), ] +# xCCH definition xCCH = ConvolutionalCode( 224, CCH_poly, name = "xcch", - description =""" *CCH convolutional code: - 228 bits blocks, rate 1/2, k = 5 - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "xCCH convolutional code:", + "228 bits blocks, rate 1/2, k = 5", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# CS2 definition CS2 = ConvolutionalCode( 290, CCH_poly, puncture = [ - 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, - 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, - 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, - 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, - 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, - 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, - 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, - 563, 571, 575, 579, 583, 587, -1 - ], + 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71, + 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, + 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195, + 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255, + 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379, + 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499, + 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559, + 563, 571, 575, 579, 583, 587, -1 + ], name = "cs2", - description =""" CS2 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "CS2 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# CS3 definition CS3 = ConvolutionalCode( 334, CCH_poly, puncture = [ - 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, - 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, - 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, - 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, - 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, - 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, - 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, - 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, - 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, - 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, - 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, - 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, - 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, - 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, - 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, - 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 - ], + 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53, + 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95, + 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137, + 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179, + 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, + 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263, + 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305, + 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347, + 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389, + 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431, + 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, + 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515, + 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557, + 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599, + 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641, + 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1 + ], name = "cs3", - description =""" CS3 convolutional code: - G0 = 1 + D3 + D4 - G1 = 1 + D + D3 + D4 -""" + description = [ + "CS3 convolutional code:", + "G0 = 1 + D3 + D4", + "G1 = 1 + D + D3 + D4", + ] ) +# TCH_AFS_12_2 definition TCH_AFS_12_2 = ConvolutionalCode( 250, [ ( 1, 1 ), ( G1, G0 ), ], - puncture = [ - 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, - 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, - 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, - 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, - 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, - -1 - ], + puncture = [ + 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, + 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, + 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441, + 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477, + 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, + -1 + ], name = 'tch_afs_12_2', - description = """TCH/AFS 12.2 convolutional code: - 250 bits block, rate 1/2, punctured - G0/G0 = 1 - G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4 -""" + description = [ + "TCH/AFS 12.2 kbits convolutional code:", + "250 bits block, rate 1/2, punctured", + "G0/G0 = 1", + "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4", + ] ) +# TCH_AFS_10_2 definition TCH_AFS_10_2 = ConvolutionalCode( 210, [ @@ -283,32 +322,34 @@ ( 1, 1 ), ], puncture = [ - 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, - 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, - 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, - 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, - 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, - 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, - 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, - 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, - 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, - 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, - 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, - 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, - 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, - 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, - 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, - 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, - 639, 640, -1 - ], + 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, + 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91, + 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139, + 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187, + 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235, + 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283, + 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328, + 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, + 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, + 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, + 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, + 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, + 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, + 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, + 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613, + 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637, + 639, 640, -1 + ], name = 'tch_afs_10_2', - description = """TCH/AFS 10.2 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 10.2 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] ) +# TCH_AFS_7_95 definition TCH_AFS_7_95 = ConvolutionalCode( 165, [ @@ -317,21 +358,23 @@ ( G6, G4 ), ], puncture = [ - 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, - 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, - 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, - 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, - 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, - 506, 508, 509, 511, 512, -1 - ], + 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, + 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367, + 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415, + 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463, + 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505, + 506, 508, 509, 511, 512, -1 + ], name = 'tch_afs_7_95', - description = """TCH/AFS 7.95 kbits convolutional code: - G4/G4 = 1 - G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6 - G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6 -""" + description = [ + "TCH/AFS 7.95 kbits convolutional code:", + "G4/G4 = 1", + "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6", + "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6", + ] ) +# TCH_AFS_7_4 definition TCH_AFS_7_4 = ConvolutionalCode( 154, [ @@ -340,18 +383,20 @@ ( 1, 1 ), ], puncture = [ - 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, - 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, - 471, 472, -1 - ], + 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, + 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, + 471, 472, -1 + ], name = 'tch_afs_7_4', - description = """TCH/AFS 7.4 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 7.4 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + ] ) +# TCH_AFS_6_7 definition TCH_AFS_6_7 = ConvolutionalCode( 140, [ @@ -361,27 +406,29 @@ ( 1, 1 ), ], puncture = [ - 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, - 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, - 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, - 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, - 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, - 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, - 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, - 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, - 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, - 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, - 561, 563, 565, 567, 569, 571, 573, 575, -1 - ], + 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, + 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267, + 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327, + 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371, + 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403, + 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435, + 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467, + 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499, + 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531, + 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559, + 561, 563, 565, 567, 569, 571, 573, 575, -1 + ], name = 'tch_afs_6_7', - description = """TCH/AFS 6.7 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 6.7 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] ) +# TCH_AFS_5_9 definition TCH_AFS_5_9 = ConvolutionalCode( 124, [ @@ -391,24 +438,26 @@ ( 1, 1), ], puncture = [ - 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, - 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, - 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, - 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, - 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, - -1 - ], + 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, + 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375, + 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439, + 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519, + -1 + ], name = 'tch_afs_5_9', - description = """TCH/AFS 5.9 kbits convolutional code: - 124 bits - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" + description = [ + "TCH/AFS 5.9 kbits convolutional code:", + "124 bits", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] ) +# TCH_AFS_5_15 definition TCH_AFS_5_15 = ConvolutionalCode( 109, [ @@ -419,27 +468,29 @@ ( 1, 1 ), ], puncture = [ - 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, - 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, - 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, - 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, - 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, - 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, - 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, - 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, - 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, - 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 - ], + 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, + 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, + 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345, + 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385, + 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425, + 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465, + 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505, + 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540, + 544, 545, 549, 550, 554, 555, 559, 560, 564, -1 + ], name = 'tch_afs_5_15', - description = """TCH/AFS 5.15 kbits convolutional code: - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4 - G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4 - G3/G3 = 1 - G3/G3 = 1 -""" + description = [ + "TCH/AFS 5.15 kbits convolutional code:", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4", + "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4", + "G3/G3 = 1", + "G3/G3 = 1", + ] ) +# TCH_AFS_4_75 definition TCH_AFS_4_75 = ConvolutionalCode( 101, [ @@ -450,23 +501,24 @@ ( 1, 1 ), ], puncture = [ - 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, - 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, - 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, - 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, - 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, - 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, - 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, - 531, 532, 534, -1 - ], + 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, + 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, + 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, + 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405, + 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460, + 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509, + 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530, + 531, 532, 534, -1 + ], name = 'tch_afs_4_75', - description = """TCH/AFS 4.75 kbits convolutional code: - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6 - G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6 - G6/G6 = 1 - G6/G6 = 1 -""" + description = [ + "TCH/AFS 4.75 kbits convolutional code:", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6", + "G6/G6 = 1", + "G6/G6 = 1", + ] ) def gen_c(dest, pref, code): -- To view, visit https://gerrit.osmocom.org/827 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8550910b9f5c16efc6f15f23c7ee52122c588752 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Sep 24 13:09:47 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 24 Sep 2016 13:09:47 +0000 Subject: [PATCH] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/691 to look at the new patch set (#12). DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M include/osmo-bts/msg_utils.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 9 files changed, 83 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/91/691/12 diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index cde7a93..f03eb43 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -10,6 +10,9 @@ struct msgb; +/* Access 1st byte of msgb control buffer */ +#define rtpmsg_marker_bit(x) ((x)->cb[0]) + /** * Classification of OML message. ETSI for plain GSM 12.21 * messages and IPA/Osmo for manufacturer messages. diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..943bdfe 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -46,6 +46,7 @@ #include #include #include +#include struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx, unsigned int chan_nr) @@ -659,7 +660,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +692,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = rtpmsg_marker_bit(resp_msg); + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +706,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1055,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1068,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + rtpmsg_marker_bit(msg) = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 21d047a..0779dac 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -503,7 +504,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index f01fdc2..88d71bf 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -90,7 +90,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 3c6ee25..e06c4cf 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -283,6 +286,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -293,10 +297,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -323,11 +330,21 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 41b09a1..3c6db43 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -496,6 +497,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 49b7e67..a90c39b 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 745923c..b1ab086 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -380,6 +383,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -390,10 +394,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -422,11 +429,21 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 12 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 24 14:30:37 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Sat, 24 Sep 2016 14:30:37 +0000 Subject: [PATCH] libosmo-abis[master]: Bump minimum oRTP version Message-ID: Review at https://gerrit.osmocom.org/934 Bump minimum oRTP version Require version 0.22.0 which matches Debian stable ATM to simplify testing and maintenance across all supported BTS models and corresponding toolchains. Change-Id: I005d60bb50889edad3e6fc0cd9f7f180aeaf1dab Fixes: SYS#2569 --- M configure.ac M src/trau/osmo_ortp.c 2 files changed, 3 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/34/934/1 diff --git a/configure.ac b/configure.ac index 7d88eb4..92cba96 100644 --- a/configure.ac +++ b/configure.ac @@ -33,15 +33,7 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.10) -PKG_CHECK_MODULES([ORTP], [ortp >= 0.13.1], - [ - PKG_CHECK_MODULES([ORTP_VERSION], [ortp >= 0.21], - [AC_DEFINE(HAVE_ORTP_021, 1, - [libortp >= 0.21])], - [AC_DEFINE(HAVE_ORTP_021, 0, - [libortp < 0.21])]) - ] -) +PKG_CHECK_MODULES(ORTP, ortp >= 0.22.0) AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built)) diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index 0bb1197..5441337 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -357,13 +357,9 @@ */ int osmo_rtp_socket_bind(struct osmo_rtp_socket *rs, const char *ip, int port) { - int rc; -#if HAVE_ORTP_021 - int rtcp = (-1 != port) ? port + 1 : -1; + int rc, rtcp = (-1 != port) ? port + 1 : -1; rc = rtp_session_set_local_addr(rs->sess, ip, port, rtcp); -#else - rc = rtp_session_set_local_addr(rs->sess, ip, port); -#endif + if (rc < 0) return rc; @@ -600,11 +596,9 @@ *recv_lost = stats->cum_packet_loss; } -#if HAVE_ORTP_021 const jitter_stats_t *jitter; jitter = rtp_session_get_jitter_stats(rs->sess); if (jitter) *last_jitter = jitter->jitter; -#endif } -- To view, visit https://gerrit.osmocom.org/934 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I005d60bb50889edad3e6fc0cd9f7f180aeaf1dab Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 24 15:02:26 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 15:02:26 +0000 Subject: osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Patch Set 12: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 12 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 15:02:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 15:02:36 +0000 Subject: [MERGED] osmo-bts[master]: DTX: check Marker bit to send ONSET to L1 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: DTX: check Marker bit to send ONSET to L1 ...................................................................... DTX: check Marker bit to send ONSET to L1 If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750 --- M include/osmo-bts/l1sap.h M include/osmo-bts/msg_utils.h M src/common/l1sap.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 9 files changed, 83 insertions(+), 24 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 2735574..981cd75 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -55,7 +55,7 @@ /* call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); + unsigned int rtp_pl_len, bool marker); /* channel control */ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index cde7a93..f03eb43 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -10,6 +10,9 @@ struct msgb; +/* Access 1st byte of msgb control buffer */ +#define rtpmsg_marker_bit(x) ((x)->cb[0]) + /** * Classification of OML message. ETSI for plain GSM 12.21 * messages and IPA/Osmo for manufacturer messages. diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7eb0b62..943bdfe 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include @@ -46,6 +46,7 @@ #include #include #include +#include struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx, unsigned int chan_nr) @@ -659,7 +660,7 @@ struct osmo_phsap_prim *resp_l1sap, empty_l1sap; struct gsm_time g_time; struct gsm_lchan *lchan; - uint8_t chan_nr; + uint8_t chan_nr, marker = 0; uint32_t fn; chan_nr = rts_ind->chan_nr; @@ -691,6 +692,9 @@ gsm_lchan_name(lchan)); resp_l1sap = &empty_l1sap; } else { + /* Obtain RTP header Marker bit from control buffer */ + marker = rtpmsg_marker_bit(resp_msg); + resp_msg->l2h = resp_msg->data; msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; @@ -702,6 +706,7 @@ resp_msg); resp_l1sap->u.tch.chan_nr = chan_nr; resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = marker; DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr); @@ -1050,7 +1055,7 @@ /*! \brief call-back function for incoming RTP */ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) + unsigned int rtp_pl_len, bool marker) { struct gsm_lchan *lchan = rs->priv; struct msgb *msg, *tmp; @@ -1063,6 +1068,8 @@ memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); msgb_pull(msg, sizeof(*l1sap)); + /* Store RTP header Marker bit in control buffer */ + rtpmsg_marker_bit(msg) = marker; /* make sure the queue doesn't get too long */ llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 21d047a..0779dac 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -469,7 +469,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -503,7 +504,13 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - msgb_free(msg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + + if (msg) + msgb_free(msg); return 0; } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index f01fdc2..88d71bf 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -90,7 +90,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 3c6ee25..e06c4cf 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -222,6 +222,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -283,6 +286,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -293,10 +297,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -323,11 +330,21 @@ rtp_pl_len); break; case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 41b09a1..3c6db43 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -462,7 +462,8 @@ if (!l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn)) { + msg->data, msg->len, u32Fn, + l1sap->u.tch.marker)) { msgb_free(nmsg); nmsg = NULL; } @@ -496,6 +497,11 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + l1sap->u.tch.marker = 0; + return ph_tch_req(trx, l1sap->oph.msg, l1sap); + } + return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 49b7e67..a90c39b 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,8 @@ /* tch.c */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn); + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, + bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 745923c..b1ab086 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -319,6 +319,9 @@ cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); break; + case AMR_NO_DATA: + LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); + break; case AMR_SID: LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", sti ? "UPDATE" : "FIRST", cmi); @@ -380,6 +383,7 @@ /*! \brief function for incoming RTP via TCH.req * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl + * \param[in] marker RTP header Marker bit (indicates speech onset) * \returns true if encoding result can be sent further to L1, false otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and @@ -390,10 +394,13 @@ * pre-fill the primtive. */ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, - const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn) + const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload; + uint8_t *l1_payload, cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -422,11 +429,21 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + if (marker) { + *payload_type = GsmL1_TchPlType_Amr_Onset; + rc = 0; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, + &bfi, &sti); + LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + get_value_string(osmo_amr_type_names, ft)); + } + else { + *payload_type = GsmL1_TchPlType_Amr; + rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, + rtp_pl_len, lchan, fn); + if (-EALREADY == rc) + return false; + } break; default: /* we don't support CSD modes */ -- To view, visit https://gerrit.osmocom.org/691 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Gerrit-PatchSet: 12 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Sep 24 15:03:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 15:03:06 +0000 Subject: libosmo-abis[master]: Bump minimum oRTP version In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/934 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I005d60bb50889edad3e6fc0cd9f7f180aeaf1dab Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Sep 24 15:03:10 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 24 Sep 2016 15:03:10 +0000 Subject: [MERGED] libosmo-abis[master]: Bump minimum oRTP version In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Bump minimum oRTP version ...................................................................... Bump minimum oRTP version Require version 0.22.0 which matches Debian stable ATM to simplify testing and maintenance across all supported BTS models and corresponding toolchains. Change-Id: I005d60bb50889edad3e6fc0cd9f7f180aeaf1dab Fixes: SYS#2569 --- M configure.ac M src/trau/osmo_ortp.c 2 files changed, 3 insertions(+), 17 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 7d88eb4..92cba96 100644 --- a/configure.ac +++ b/configure.ac @@ -33,15 +33,7 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.10) -PKG_CHECK_MODULES([ORTP], [ortp >= 0.13.1], - [ - PKG_CHECK_MODULES([ORTP_VERSION], [ortp >= 0.21], - [AC_DEFINE(HAVE_ORTP_021, 1, - [libortp >= 0.21])], - [AC_DEFINE(HAVE_ORTP_021, 0, - [libortp < 0.21])]) - ] -) +PKG_CHECK_MODULES(ORTP, ortp >= 0.22.0) AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built)) diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index 0bb1197..5441337 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -357,13 +357,9 @@ */ int osmo_rtp_socket_bind(struct osmo_rtp_socket *rs, const char *ip, int port) { - int rc; -#if HAVE_ORTP_021 - int rtcp = (-1 != port) ? port + 1 : -1; + int rc, rtcp = (-1 != port) ? port + 1 : -1; rc = rtp_session_set_local_addr(rs->sess, ip, port, rtcp); -#else - rc = rtp_session_set_local_addr(rs->sess, ip, port); -#endif + if (rc < 0) return rc; @@ -600,11 +596,9 @@ *recv_lost = stats->cum_packet_loss; } -#if HAVE_ORTP_021 const jitter_stats_t *jitter; jitter = rtp_session_get_jitter_stats(rs->sess); if (jitter) *last_jitter = jitter->jitter; -#endif } -- To view, visit https://gerrit.osmocom.org/934 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I005d60bb50889edad3e6fc0cd9f7f180aeaf1dab Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Sep 25 14:57:29 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 14:57:29 +0000 Subject: openbsc[master]: bts: extend bts_chan_load to allow counting tch only In-Reply-To: References: Message-ID: Patch Set 2: (2 comments) https://gerrit.osmocom.org/#/c/793/2/openbsc/src/libbsc/chan_alloc.c File openbsc/src/libbsc/chan_alloc.c: Line 523: case GSM_PCHAN_TCH_F_PDCH: This is actually wrong, GSM_PCHAN_TCH_F_PDCH use ts->flags, not ts->dyn below (due to historical reasons and could be unified). This is already committed, and I'm also touching this code today; so don't worry, I will send a patch that fixes this. Line 560: if (only_count_tch && !chan_is_tch(ts)) This has exactly one effect: it excludes GSM_PCHAN_TCH_F_PDCH when in PDCH mode, because for all other PDCH (plain PDCH and TCH/F_TCH/H_PDCH in PDCH mode) below ts_subslots() returns 0 and skips the for() loop. I consider this a bug in TCH/F_PDCH (which I coincidentally found and then saw this patch; am fixing things now). The point is, I don't see why we need the only_count_tch argument, because this should normally only count TCH, weren't it for the TCH/F_PDCH bug. If dyn TS should be counted differently, we should do this in a different way. My apologies, but all in all I would actually like to revert this commit. Also apologies for not seeing this sooner, it's been sitting here for quite a while now. -- To view, visit https://gerrit.osmocom.org/793 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I86f1d502649747b6b9aefcb39081b14110e8f494 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: lynxis lazus Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Sep 25 14:58:25 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 14:58:25 +0000 Subject: [PATCH] openbsc[master]: cosmetic: comment typo on e1_config.c Message-ID: Review at https://gerrit.osmocom.org/935 cosmetic: comment typo on e1_config.c Change-Id: I894adf562670abf26665a1eb09592682ab8b31b5 --- M openbsc/src/libbsc/e1_config.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/35/935/1 diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index d82b009..803772b 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -37,7 +37,7 @@ #define SAPI_OML 62 #define SAPI_RSL 0 /* 63 ? */ -/* The e1_reconfig_*() functions below tale the configuration present in the +/* The e1_reconfig_*() functions below take the configuration present in the * bts/trx/ts data structures and ensure the E1 configuration reflects the * timeslot/subslot/TEI configuration */ -- To view, visit https://gerrit.osmocom.org/935 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I894adf562670abf26665a1eb09592682ab8b31b5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:33 +0000 Subject: [PATCH] openbsc[master]: channel test: prepare to add another test function Message-ID: Review at https://gerrit.osmocom.org/936 channel test: prepare to add another test function Move the main() guts to test_request_chan(), so that I can add another test in an upcoming commit. Change-Id: I1349d0f416806416080d4667ad697f7db1ea252d --- M openbsc/tests/channel/channel_test.c 1 file changed, 8 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/36/936/1 diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 5674607..e339bff 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -58,12 +58,10 @@ } -int main(int argc, char **argv) +void test_request_chan(void) { struct gsm_network *network; struct gsm_bts *bts; - - osmo_init_logging(&log_info); printf("Testing the gsm_subscriber chan logic\n"); @@ -90,6 +88,13 @@ s_cbfn(101, 200, (void*)0x1323L, &s_conn, s_data); OSMO_ASSERT(s_end); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&log_info); + + test_request_chan(); return EXIT_SUCCESS; } -- To view, visit https://gerrit.osmocom.org/936 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1349d0f416806416080d4667ad697f7db1ea252d Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:33 +0000 Subject: [PATCH] openbsc[master]: channel_test: test nr of subslots for dyn pchan, with error Message-ID: Review at https://gerrit.osmocom.org/937 channel_test: test nr of subslots for dyn pchan, with error Add test_dyn_ts_subslots() and call from main(). Update channel_test.ok. This includes erratic assert to show a bug for TCH/F_PDCH in PDCH mode: the nr of subslots should be the same as for a normal PDCH, i.e. zero. This will be adjusted along with the fix in an upcoming commit. Change-Id: I09685be3fb3ed1ead4577b772a9fbc31967980d1 --- M openbsc/tests/channel/channel_test.c M openbsc/tests/channel/channel_test.ok 2 files changed, 32 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/37/937/1 diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index e339bff..e6d6925 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -90,11 +90,42 @@ OSMO_ASSERT(s_end); } +void test_dyn_ts_subslots(void) +{ + struct gsm_bts_trx_ts ts; + + printf("Testing subslot numbers for pchan types\n"); + + ts.pchan = GSM_PCHAN_TCH_F; + OSMO_ASSERT(ts_subslots(&ts) == 1); + + ts.pchan = GSM_PCHAN_TCH_H; + OSMO_ASSERT(ts_subslots(&ts) == 2); + + ts.pchan = GSM_PCHAN_PDCH; + OSMO_ASSERT(ts_subslots(&ts) == 0); + + ts.pchan = GSM_PCHAN_TCH_F_PDCH; + ts.flags = 0; /* TCH_F mode */ + OSMO_ASSERT(ts_subslots(&ts) == 1); + ts.flags = TS_F_PDCH_ACTIVE; + OSMO_ASSERT(ts_subslots(&ts) == 1 /* SHOULD BE 0 */); + + ts.pchan = GSM_PCHAN_TCH_F_TCH_H_PDCH; + ts.dyn.pchan_is = GSM_PCHAN_TCH_F; + OSMO_ASSERT(ts_subslots(&ts) == 1); + ts.dyn.pchan_is = GSM_PCHAN_TCH_H; + OSMO_ASSERT(ts_subslots(&ts) == 2); + ts.dyn.pchan_is = GSM_PCHAN_PDCH; + OSMO_ASSERT(ts_subslots(&ts) == 0); +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); test_request_chan(); + test_dyn_ts_subslots(); return EXIT_SUCCESS; } diff --git a/openbsc/tests/channel/channel_test.ok b/openbsc/tests/channel/channel_test.ok index 7976aee..33c8193 100644 --- a/openbsc/tests/channel/channel_test.ok +++ b/openbsc/tests/channel/channel_test.ok @@ -1,2 +1,3 @@ Testing the gsm_subscriber chan logic Reached, didn't crash, test passed +Testing subslot numbers for pchan types -- To view, visit https://gerrit.osmocom.org/937 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I09685be3fb3ed1ead4577b772a9fbc31967980d1 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:34 +0000 Subject: [PATCH] openbsc[master]: Revert "bts: extend bts_chan_load to allow counting tch only" Message-ID: Review at https://gerrit.osmocom.org/938 Revert "bts: extend bts_chan_load to allow counting tch only" This reverts commit 308cb0719dca3ba8eed1eff2a2124d44f34d9a28. Problems in this commit: openbsc/src/libbsc/chan_alloc.c:523: case GSM_PCHAN_TCH_F_PDCH: This is actually wrong, GSM_PCHAN_TCH_F_PDCH use ts->flags, not ts->dyn below (due to historical reasons and could be unified). 560: if (only_count_tch && !chan_is_tch(ts)) This has exactly one effect: it excludes GSM_PCHAN_TCH_F_PDCH when in PDCH mode, because for all other PDCH (plain PDCH and TCH/F_TCH/H_PDCH in PDCH mode) below ts_subslots() returns 0 and skips the for() loop. I consider this a bug in TCH/F_PDCH, to be fixed in an upcoming commit. I don't see why we need the only_count_tch argument, because this should normally only count TCH, weren't it for the TCH/F_PDCH bug. If dyn TS should be counted differently, we should do this in a different way. Change-Id: I34dbbaf53a800115e3d03bd44028cad675f3b525 --- M openbsc/include/openbsc/chan_alloc.h M openbsc/src/libbsc/bsc_ctrl_commands.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/chan_alloc.c M openbsc/src/libbsc/paging.c 5 files changed, 7 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/38/938/1 diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h index d919b51..78242e5 100644 --- a/openbsc/include/openbsc/chan_alloc.h +++ b/openbsc/include/openbsc/chan_alloc.h @@ -46,7 +46,7 @@ struct load_counter pchan[_GSM_PCHAN_MAX]; }; -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, int only_count_tch); +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts); void network_chan_load(struct pchan_load *pl, struct gsm_network *net); int trx_is_usable(struct gsm_bts_trx *trx); diff --git a/openbsc/src/libbsc/bsc_ctrl_commands.c b/openbsc/src/libbsc/bsc_ctrl_commands.c index 3f4fee2..7e84797 100644 --- a/openbsc/src/libbsc/bsc_ctrl_commands.c +++ b/openbsc/src/libbsc/bsc_ctrl_commands.c @@ -239,7 +239,7 @@ bts = cmd->node; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); cmd->reply = talloc_strdup(cmd, ""); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 01eec23..5c95e85 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -329,7 +329,7 @@ /* FIXME: chan_desc */ memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE); dump_pchan_load_vty(vty, " ", &pl); } diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c index 03d44e0..7b0c3e6 100644 --- a/openbsc/src/libbsc/chan_alloc.c +++ b/openbsc/src/libbsc/chan_alloc.c @@ -514,28 +514,7 @@ return NULL; } -static int chan_is_tch(struct gsm_bts_trx_ts *ts) -{ - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: - return 1; - case GSM_PCHAN_TCH_F_PDCH: - case GSM_PCHAN_TCH_F_TCH_H_PDCH: - if (ts->dyn.pchan_is == GSM_PCHAN_TCH_F || - ts->dyn.pchan_is == GSM_PCHAN_TCH_H) - return 1; - else - return 0; - default: - return 0; - } -} - - - -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, - int only_count_tch) +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts) { struct gsm_bts_trx *trx; @@ -555,9 +534,6 @@ /* skip administratively deactivated timeslots */ if (!nm_is_running(&ts->mo.nm_state)) - continue; - - if (only_count_tch && !chan_is_tch(ts)) continue; subslots = ts_subslots(ts); @@ -585,5 +561,6 @@ memset(pl, 0, sizeof(*pl)); llist_for_each_entry(bts, &net->bts_list, list) - bts_chan_load(pl, bts, 0); + bts_chan_load(pl, bts); } + diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index e3795b3..fcb4deb 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -119,7 +119,7 @@ int count; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); switch (rsl_type) { case RSL_CHANNEED_TCH_F: -- To view, visit https://gerrit.osmocom.org/938 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I34dbbaf53a800115e3d03bd44028cad675f3b525 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:34 +0000 Subject: [PATCH] openbsc[master]: dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode Message-ID: Review at https://gerrit.osmocom.org/939 dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode In gsm_data_shared.c, add ts_pchan() to determine actual pchan type for dynamic and non-dynamic TS. Use in ts_subslots() to fix the value returned for TCH/F_PDCH in PDCH mode. Adjust the assertion in channel_test.c accordingly. Drop GSM_PCHAN_TCH_F_PDCH, which is now handled in ts_pchan(). Explicitly add GSM_PCHAN_PDCH as zero in subslots_per_pchan[] (cosmetic). Adjust the comment in subslots_per_pchan[]. The fix for the number of subslots affects only one caller: bts_chan_load() in chan_alloc.c. Before this, it would always include a TCH/F_PDCH in the load_counter->total, now it is skipped when in PDCH mode. Whether this is the way bts_chan_load() should handle dynamic TS is a separate discussion, so far I'm only making sure that the two dyn TS kinds act in the same way: TCH/F_TCH/H_PDCH is only counted when in TCH mode, and TCH/F_PDCH should match. Change-Id: Icd6668667ad2be7ad20866ffd185bf3b8711ccd6 --- M openbsc/src/libcommon/gsm_data_shared.c M openbsc/tests/channel/channel_test.c 2 files changed, 21 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/39/939/1 diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index c8c9e04..371e479 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -712,24 +712,38 @@ static const uint8_t subslots_per_pchan[] = { [GSM_PCHAN_NONE] = 0, [GSM_PCHAN_CCCH] = 0, + [GSM_PCHAN_PDCH] = 0, [GSM_PCHAN_CCCH_SDCCH4] = 4, [GSM_PCHAN_TCH_F] = 1, [GSM_PCHAN_TCH_H] = 2, [GSM_PCHAN_SDCCH8_SACCH8C] = 8, - [GSM_PCHAN_TCH_F_PDCH] = 1, [GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4, [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8, /* - * GSM_PCHAN_TCH_F_TCH_H_PDCH should not be part of this, those TS are - * handled according to their ts->dyn state. + * GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be + * part of this, those TS are handled according to their dynamic state. */ }; + +/*! Return the actual pchan type, also heeding dynamic TS. */ +static enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F_TCH_H_PDCH: + return ts->dyn.pchan_is; + case GSM_PCHAN_TCH_F_PDCH: + if (ts->flags & TS_F_PDCH_ACTIVE) + return GSM_PCHAN_PDCH; + else + return GSM_PCHAN_TCH_F; + default: + return ts->pchan; + } +} /*! According to ts->pchan and possibly ts->dyn_pchan, return the number of * logical channels available in the timeslot. */ uint8_t ts_subslots(struct gsm_bts_trx_ts *ts) { - if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) - return subslots_per_pchan[ts->dyn.pchan_is]; - return subslots_per_pchan[ts->pchan]; + return subslots_per_pchan[ts_pchan(ts)]; } diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index e6d6925..009aa56 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -109,7 +109,7 @@ ts.flags = 0; /* TCH_F mode */ OSMO_ASSERT(ts_subslots(&ts) == 1); ts.flags = TS_F_PDCH_ACTIVE; - OSMO_ASSERT(ts_subslots(&ts) == 1 /* SHOULD BE 0 */); + OSMO_ASSERT(ts_subslots(&ts) == 0); ts.pchan = GSM_PCHAN_TCH_F_TCH_H_PDCH; ts.dyn.pchan_is = GSM_PCHAN_TCH_F; -- To view, visit https://gerrit.osmocom.org/939 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icd6668667ad2be7ad20866ffd185bf3b8711ccd6 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:34 +0000 Subject: [PATCH] openbsc[master]: dyn TS: fix: bs11, om2000: two switch(pchan) for dyn TS Message-ID: Review at https://gerrit.osmocom.org/940 dyn TS: fix: bs11, om2000: two switch(pchan) for dyn TS Add ts_is_tch() in gsm_data_shared.h/.c and use it to replace a switch on the pchan in two (unrelated) places: libbsc/bts_siemens_bs11.c and e1_config.c. This patch is not due to an actual observed failure. A general grep for switch on pchan turned up these two instances that don't handle dyn TS properly. Hence this patch is not actually tested with real equipment. Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bts_siemens_bs11.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libcommon/gsm_data_shared.c 4 files changed, 19 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/40/940/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 7c8fb59..368ac6b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -855,5 +855,6 @@ int *rc); uint8_t ts_subslots(struct gsm_bts_trx_ts *ts); +bool ts_is_tch(struct gsm_bts_trx_ts *ts); #endif diff --git a/openbsc/src/libbsc/bts_siemens_bs11.c b/openbsc/src/libbsc/bts_siemens_bs11.c index 160563b..c083b1e 100644 --- a/openbsc/src/libbsc/bts_siemens_bs11.c +++ b/openbsc/src/libbsc/bts_siemens_bs11.c @@ -400,15 +400,9 @@ if (is_ipaccess_bts(ts->trx->bts)) return; - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts, e1l->e1_ts_ss); - break; - default: - break; - } } static void nm_reconfig_trx(struct gsm_bts_trx *trx) diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index d82b009..0c3250f 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -63,15 +63,10 @@ return -ENOMEM; } - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) { e1_ts = &line->ts[e1_link->e1_ts-1]; e1inp_ts_config_trau(e1_ts, line, subch_cb); subch_demux_activate(&e1_ts->trau.demux, e1_link->e1_ts_ss); - break; - default: - break; } return 0; diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 371e479..4eea21e 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -747,3 +747,19 @@ { return subslots_per_pchan[ts_pchan(ts)]; } + +static bool pchan_is_tch(enum gsm_phys_chan_config pchan) +{ + switch (pchan) { + case GSM_PCHAN_TCH_F: + case GSM_PCHAN_TCH_H: + return true; + default: + return false; + } +} + +bool ts_is_tch(struct gsm_bts_trx_ts *ts) +{ + return pchan_is_tch(ts_pchan(ts)); +} -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Sep 25 15:40:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 25 Sep 2016 15:40:34 +0000 Subject: [PATCH] openbsc[master]: dyn TS: fix: abis_om2000: also handle dyn TS as TCH Message-ID: Review at https://gerrit.osmocom.org/941 dyn TS: fix: abis_om2000: also handle dyn TS as TCH Add ts2comb() to switch on dyn TS so that dyn TS in TCH mode are also treated like normal TCH/H or TCH/F pchans. Use ts2comb() instead of pchan2comb(). Change-Id: Iddc51a4409488d91db59228ca66aaab73ce3f1df --- M openbsc/src/libbsc/abis_om2000.c 1 file changed, 16 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/41/941/1 diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c index 2e5a79a..1745a72 100644 --- a/openbsc/src/libbsc/abis_om2000.c +++ b/openbsc/src/libbsc/abis_om2000.c @@ -1123,10 +1123,24 @@ case GSM_PCHAN_TCH_F: case GSM_PCHAN_TCH_H: case GSM_PCHAN_PDCH: - case GSM_PCHAN_TCH_F_PDCH: return 8; default: return 0; + } +} + +static uint8_t ts2comb(struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F_PDCH: + if (ts->flags & TS_F_PDCH_ACTIVE) + return pchan2comb(GSM_PCHAN_PDCH); + else + return pchan2comb(GSM_PCHAN_TCH_F); + case GSM_PCHAN_TCH_F_TCH_H_PDCH: + return pchan2comb(ts->dyn.pchan_is); + default: + return pchan2comb(ts->pchan); } } @@ -1179,7 +1193,7 @@ o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TS_CONF_REQ); - msgb_tv_put(msg, OM2K_DEI_COMBINATION, pchan2comb(ts->pchan)); + msgb_tv_put(msg, OM2K_DEI_COMBINATION, ts2comb(ts)); msgb_tv_put(msg, OM2K_DEI_TS_NR, ts->nr); msgb_tlv_put(msg, OM2K_DEI_FREQ_LIST, freq_list_len, freq_list); msgb_tv_put(msg, OM2K_DEI_HSN, ts->hopping.hsn); -- To view, visit https://gerrit.osmocom.org/941 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iddc51a4409488d91db59228ca66aaab73ce3f1df Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:21:27 +0000 Subject: [PATCH] osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/909 to look at the new patch set (#2). hnbgw: UE context: add handling by tmsi identification To prepare for an upcoming commit that accepts TMSI identification upon UE Register Requests: Add tmsi arg to ue_context_alloc(). Add ue_context_by_tmsi(). This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. See the upcoming commit that enables accepting TMSI identities for further detail. Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_hnbap.c 3 files changed, 23 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/09/909/2 diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index 21a9602..bee7fb6 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -101,8 +101,7 @@ /*! Unique Context ID for this UE */ uint32_t context_id; char imsi[16+1]; - /* TODO: track TMSI, for HNBAP UE Register Request with TMSI, - * seen with ip.access nano3G femto cell */ + uint32_t tmsi; /*! UE is serviced via this HNB */ struct hnb_context *hnb; }; @@ -139,7 +138,9 @@ struct ue_context *ue_context_by_id(struct hnb_gw *gw, uint32_t id); struct ue_context *ue_context_by_imsi(struct hnb_gw *gw, const char *imsi); -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi); +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi); +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi); void ue_context_free(struct ue_context *ue); struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd); diff --git a/src/hnbgw.c b/src/hnbgw.c index d50e622..0e711db 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -111,6 +111,17 @@ return NULL; } +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi) +{ + struct ue_context *ue; + + llist_for_each_entry(ue, &gw->ue_list, list) { + if (ue->tmsi == tmsi) + return ue; + } + return NULL; +} + void ue_context_free_by_hnb(struct hnb_gw *gw, const struct hnb_context *hnb) { struct ue_context *ue, *tmp; @@ -132,7 +143,8 @@ return id; } -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi) +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi) { struct ue_context *ue; @@ -141,7 +153,11 @@ return NULL; ue->hnb = hnb; - strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + if (imsi) + strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + else + ue->imsi[0] = '\0'; + ue->tmsi = tmsi; ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index ae0d16c..78f4692 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -327,7 +327,7 @@ ue = ue_context_by_imsi(ctx->gw, imsi); if (!ue) - ue = ue_context_alloc(ctx, imsi); + ue = ue_context_alloc(ctx, imsi, 0); hnbap_free_ueregisterrequesties(&ies); /* Send UERegisterAccept */ -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:21:27 +0000 Subject: [PATCH] osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/910 to look at the new patch set (#2). hnbap: accept UE Register Requests with TMSI and pTMSI Add the option to allow UE Register Requests with a TMSI identity. Add VTY command to enable this option, 'hnbap-allow-tmsi'. Add hnbgw_tx_ue_register_acc_tmsi(). HNBGW so far keeps track of UEs that have registered, with their IMSI. When a UE registers with only a TMSI, we obviously can't store an IMSI. However, since we're so far never *using* the list of UEs in osmo-hnbgw, we might as well just accept the TMSI registration and carry on as usual. All that is needed for proper operation is a valid UE context. This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. So far this caused failures and the need to make the UE clear its TMSI (wait several minutes or attempt to subscribe to a different network), so that UE registration switched back to IMSI. When simply accepting the TMSI in osmo-hngw, no problems are apparent in our current code state. For example, a Samsung Galaxy S4 seems to send a UE_Identity_PR_tMSILAI (CS identity), and a GT-I9100 seems to send a UE_Identity_PR_pTMSIRAI (PS identity) upon first registration to the network. Recording the IMSI in hnbgw: we could use the subscriber list during paging, to page a UE on only its last seen HNB. On the other hand, it doesn't hurt to anyway always page to all HNBs connected to osmo-hnbgw. The paging procedure does include a page-to-all-HNBs in case the first HNB paging fails. But we must be aware that UEs that register by TMSI will simply not have an IMSI recorded in the list of UE contexts, so a lookup based on IMSI may fail. Patch-by: Harald Welte , me Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw_hnbap.c M src/hnbgw_vty.c 3 files changed, 130 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/10/910/2 diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index bee7fb6..dfe287c 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -117,6 +117,7 @@ * plane traffic from HNBs */ uint16_t iuh_cs_mux_port; uint16_t rnc_id; + bool hnbap_allow_tmsi; } config; /*! SCTP listen socket for incoming connections */ struct osmo_stream_srv_link *iuh; diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 78f4692..59150c9 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -244,6 +244,108 @@ return hnbgw_hnbap_tx(hnb, msg); } +static int hnbgw_tx_ue_register_acc_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id) +{ + UERegisterAccept_t accept_out; + UERegisterAcceptIEs_t accept; + struct msgb *msg; + uint32_t ctx_id; + uint32_t tmsi = 0; + struct ue_context *ue; + int rc; + + memset(&accept, 0, sizeof(accept)); + accept.uE_Identity.present = ue_id->present; + + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.tMSILAI.tMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + break; + + case UE_Identity_PR_pTMSIRAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.pTMSI, + ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size * 8 + - ue_id->choice.pTMSIRAI.pTMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.pTMSIRAI.pTMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.rAC, + ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size); + break; + + default: + LOGP(DHNBAP, LOGL_ERROR, "Unsupportedccept UE ID (present=%d)\n", + ue_id->present); + return -1; + } + + tmsi = ntohl(tmsi); + LOGP(DHNBAP, LOGL_DEBUG, "HNBAP register with TMSI %x\n", + tmsi); + + ue = ue_context_by_tmsi(hnb->gw, tmsi); + if (!ue) + ue = ue_context_alloc(hnb, NULL, tmsi); + + asn1_u24_to_bitstring(&accept.context_ID, &ctx_id, ue->context_id); + + memset(&accept_out, 0, sizeof(accept_out)); + rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept); + if (rc < 0) + return rc; + + msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister, + Criticality_reject, + &asn_DEF_UERegisterAccept, + &accept_out); + + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.lAC); + break; + + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + + default: + /* should never happen after above switch() */ + break; + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterAccept, &accept_out); + + return hnbgw_hnbap_tx(hnb, msg); +} + static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in) { HNBDe_RegisterIEs_t ies; @@ -313,11 +415,19 @@ ranap_bcd_decode(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf, ies.uE_Identity.choice.iMSIESN.iMSIDS41.size); break; + case UE_Identity_PR_tMSILAI: + case UE_Identity_PR_pTMSIRAI: + if (ctx->gw->config.hnbap_allow_tmsi) + rc = hnbgw_tx_ue_register_acc_tmsi(ctx, &ies.uE_Identity); + else + rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); + /* all has been handled by TMSI, skip the IMSI code below */ + hnbap_free_ueregisterrequesties(&ies); + return rc; default: - LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n"); - /* TODO: this is probably a TMSI registration. Store TMSIs - * and look them up to accept UE Registration. */ - rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); + LOGP(DHNBAP, LOGL_NOTICE, + "UE-REGISTER-REQ with unsupported UE Id type %d\n", + ies.uE_Identity.present); hnbap_free_ueregisterrequesties(&ies); return rc; } diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index 2e3d1e9..d6fad64 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -114,6 +114,16 @@ return CMD_SUCCESS; } +DEFUN(cfg_hnbgw_iuh_hnbap_allow_tmsi, cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd, + "hnbap-allow-tmsi (0|1)", + "Allow HNBAP UE Register messages with TMSI or PTMSI identity\n" + "Only accept IMSI identity, reject TMSI or PTMSI\n" + "Accept IMSI, TMSI or PTMSI as UE identity\n") +{ + g_hnb_gw->config.hnbap_allow_tmsi = (*argv[0] == '1'); + return CMD_SUCCESS; +} + static int config_write_hnbgw(struct vty *vty) { vty_out(vty, "hnbgw%s", VTY_NEWLINE); @@ -130,6 +140,9 @@ if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0)) vty_out(vty, " bind %s%s", addr, VTY_NEWLINE); + if (g_hnb_gw->config.hnbap_allow_tmsi) + vty_out(vty, " hnbap-allow-tmsi 1%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -145,7 +158,9 @@ install_element(HNBGW_NODE, &cfg_hnbgw_iuh_cmd); install_node(&iuh_node, config_write_hnbgw_iuh); vty_install_default(IUH_NODE); + install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd); + install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd); install_element_ve(&show_hnb_cmd); install_element_ve(&show_ue_cmd); -- To view, visit https://gerrit.osmocom.org/910 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:21:27 +0000 Subject: [PATCH] osmo-iuh[master]: hnbap: add UE Register Reject for pTMSIRAI identity Message-ID: Review at https://gerrit.osmocom.org/942 hnbap: add UE Register Reject for pTMSIRAI identity This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. Sending a proper registration reject speeds up the response seen on the UE and avoids needless waiting. See the upcoming commit that enables accepting TMSI identities for further detail. Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c --- M src/hnbgw_hnbap.c 1 file changed, 99 insertions(+), 32 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/42/942/1 diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 7bf54c8..ae0d16c 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -124,54 +124,121 @@ memset(&reject, 0, sizeof(reject)); reject.uE_Identity.present = ue_id->present; - if (ue_id->present != UE_Identity_PR_tMSILAI) { - LOGP(DHNBAP, LOGL_ERROR, "Trying to reject UE Register without IMSI: only rejects of UE_Identity_PR_tMSILAI supported so far.\n"); + /* Copy the identity over to the reject message */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", + ue_id->choice.tMSILAI.tMSI.size, + osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.tMSILAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.tMSILAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size)); + + BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + break; + + case UE_Identity_PR_pTMSIRAI: + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pTMSI %d %s\n", + ue_id->choice.pTMSIRAI.pTMSI.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id rAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.rAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size)); + + BIT_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.pTMSI, + ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size * 8 + - ue_id->choice.pTMSIRAI.pTMSI.bits_unused); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.rAC, + ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size); + break; + + default: + LOGP(DHNBAP, LOGL_ERROR, "Cannot compose UE Register Reject:" + " unsupported UE ID (present=%d)\n", ue_id->present); return -1; } - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", - ue_id->choice.tMSILAI.tMSI.size, - osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size)); - - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", - ue_id->choice.tMSILAI.lAI.pLMNID.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size)); - - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", - ue_id->choice.tMSILAI.lAI.lAC.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size)); - - BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, - ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size * 8 - - ue_id->choice.tMSILAI.tMSI.bits_unused); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, - ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, - ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size); + LOGP(DHNBAP, LOGL_ERROR, "Rejecting UE Register Request:" + " TMSI identity registration is switched off\n"); reject.cause.present = Cause_PR_radioNetwork; reject.cause.choice.radioNetwork = CauseRadioNetwork_invalid_UE_identity; memset(&reject_out, 0, sizeof(reject_out)); rc = hnbap_encode_ueregisterrejecties(&reject_out, &reject); - if (rc < 0) { + if (rc < 0) return rc; - } msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister, Criticality_reject, &asn_DEF_UERegisterReject, &reject_out); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, &reject.uE_Identity.choice.tMSILAI.tMSI); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.lAC); + /* Free copied identity IEs */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &reject.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.tMSILAI.lAI.lAC); + break; + + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &reject.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + + default: + /* should never happen after above switch() */ + break; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out); return hnbgw_hnbap_tx(hnb, msg); -- To view, visit https://gerrit.osmocom.org/942 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:21:27 +0000 Subject: [PATCH] osmo-iuh[master]: log: hnbgw: add hnbap UE context allocation info log Message-ID: Review at https://gerrit.osmocom.org/943 log: hnbgw: add hnbap UE context allocation info log Change-Id: Iac0ca948d6e699d984c6e424afe7106dcaf2ab1e --- M src/hnbgw.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/43/943/1 diff --git a/src/hnbgw.c b/src/hnbgw.c index 0e711db..d375e27 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -161,6 +161,9 @@ ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); + LOGP(DHNBAP, LOGL_INFO, "created UE context: id 0x%x, imsi %s, tmsi 0x%x\n", + ue->context_id, imsi? imsi : "-", tmsi); + return ue; } -- To view, visit https://gerrit.osmocom.org/943 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iac0ca948d6e699d984c6e424afe7106dcaf2ab1e Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:21:27 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:21:27 +0000 Subject: [PATCH] osmo-iuh[master]: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' Message-ID: Review at https://gerrit.osmocom.org/944 hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' The standard osmo VTY terminology is 'remote-ip', 'remote-port', 'local-ip', 'local-port'. Conform to that. osmo-hnbgw is so far not rolled out widely, so it makes sense to do this now. Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_vty.c 3 files changed, 6 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/44/944/1 diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index dfe287c..dfc9d82 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -106,7 +106,7 @@ struct hnb_context *hnb; }; -#define HNBGW_IUH_BIND_ADDR_DEFAULT "0.0.0.0" +#define HNBGW_IUH_LOCAL_IP_DEFAULT "0.0.0.0" struct hnb_gw { struct { diff --git a/src/hnbgw.c b/src/hnbgw.c index d375e27..e44d872 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -312,7 +312,7 @@ { const char *addr = gw->config.iuh_bind_addr; if (!addr) - addr = HNBGW_IUH_BIND_ADDR_DEFAULT; + addr = HNBGW_IUH_LOCAL_IP_DEFAULT; return addr; } diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index d6fad64..1e19116 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -105,9 +105,9 @@ return CMD_SUCCESS; } -DEFUN(cfg_hnbgw_iuh_bind, cfg_hnbgw_iuh_bind_cmd, "bind A.B.C.D", +DEFUN(cfg_hnbgw_iuh_local_ip, cfg_hnbgw_iuh_local_ip_cmd, "local-ip A.B.C.D", "Accept Iuh connections on local interface\n" - "Local interface IP address (default: " HNBGW_IUH_BIND_ADDR_DEFAULT ")") + "Local interface IP address (default: " HNBGW_IUH_LOCAL_IP_DEFAULT ")") { talloc_free((void*)g_hnb_gw->config.iuh_bind_addr); g_hnb_gw->config.iuh_bind_addr = talloc_strdup(tall_hnb_ctx, argv[0]); @@ -137,7 +137,7 @@ vty_out(vty, " iuh%s", VTY_NEWLINE); addr = g_hnb_gw->config.iuh_bind_addr; - if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0)) + if (addr && (strcmp(addr, HNBGW_IUH_LOCAL_IP_DEFAULT) != 0)) vty_out(vty, " bind %s%s", addr, VTY_NEWLINE); if (g_hnb_gw->config.hnbap_allow_tmsi) @@ -159,7 +159,7 @@ install_node(&iuh_node, config_write_hnbgw_iuh); vty_install_default(IUH_NODE); - install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd); + install_element(IUH_NODE, &cfg_hnbgw_iuh_local_ip_cmd); install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd); install_element_ve(&show_hnb_cmd); -- To view, visit https://gerrit.osmocom.org/944 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:22 +0000 Subject: [MERGED] openbsc[master]: mscsplit: directly access gsm_network backpointer from gsm_s... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: directly access gsm_network backpointer from gsm_subscriber_connection ...................................................................... mscsplit: directly access gsm_network backpointer from gsm_subscriber_connection The previous commit added a network backpointer to gsm_subscriber_connection. Use it wherever it makes sense, to skip the step through the bts structure. In some places, remove local variables that become unused. Change-Id: I34537025986713291e14c8212a81539b497befd4 --- M openbsc/src/libbsc/bsc_api.c M openbsc/src/libmsc/gsm_04_08.c M openbsc/src/libmsc/gsm_04_11.c M openbsc/src/libmsc/rrlp.c M openbsc/src/libmsc/transaction.c 5 files changed, 53 insertions(+), 60 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 02751f4..cc12e9f 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -146,7 +146,7 @@ conn->secondary_lchan = NULL; /* inform them about the failure */ - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL); } @@ -157,7 +157,7 @@ struct gsm_lchan *lchan, int full_rate) { struct bsc_api *api; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; struct amr_multirate_conf *mr; struct gsm48_multi_rate_conf *mr_conf; @@ -387,7 +387,7 @@ int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate) { struct bsc_api *api; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; if (!chan_compat_with_mode(conn->lchan, chan_mode, full_rate)) { if (handle_new_assignment(conn, chan_mode, full_rate) != 0) @@ -424,7 +424,7 @@ struct msgb *msg) { struct gsm48_hdr *gh; - struct bsc_api *api = conn->bts->network->bsc_api; + struct bsc_api *api = conn->network->bsc_api; if (conn->secondary_lchan != msg->lchan) { LOGP(DMSC, LOGL_ERROR, "Assignment Compl should occur on second lchan.\n"); @@ -461,7 +461,7 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct bsc_api *api = conn->bts->network->bsc_api; + struct bsc_api *api = conn->network->bsc_api; uint8_t *rr_failure; struct gsm48_hdr *gh; @@ -751,7 +751,7 @@ if (!conn) return; - api = conn->bts->network->bsc_api; + api = conn->network->bsc_api; if (!api || !api->sapi_n_reject) return; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 08dac63..aa3d78a9 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -187,7 +187,7 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, gsm_cbfn *cb, void *cb_data) { - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_subscriber *subscr = conn->subscr; struct gsm_security_operation *op; struct gsm_auth_tuple atuple; @@ -321,7 +321,7 @@ static int finish_lu(struct gsm_subscriber_connection *conn) { int rc = 0; - int avoid_tmsi = conn->bts->network->avoid_tmsi; + int avoid_tmsi = conn->network->avoid_tmsi; /* We're all good */ if (avoid_tmsi) { @@ -332,7 +332,7 @@ } rc = gsm0408_loc_upd_acc(conn); - if (conn->bts->network->send_mm_info) { + if (conn->network->send_mm_info) { /* send MM INFO with network name */ rc = gsm48_tx_mm_info(conn); } @@ -429,7 +429,7 @@ * we have a subscriber connection. */ restart: - llist_for_each_entry_safe(trans, temp, &conn->bts->network->trans_list, entry) { + llist_for_each_entry_safe(trans, temp, &conn->network->trans_list, entry) { if (trans->conn == conn) { trans_free(trans); goto restart; @@ -457,7 +457,7 @@ struct gsm_bts *bts = conn->bts; struct msgb *msg; - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_REJECT]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_REJECT]); msg = gsm48_create_loc_upd_rej(cause); if (!msg) { @@ -477,7 +477,6 @@ /* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn) { - struct gsm_bts *bts = conn->bts; struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC"); struct gsm48_hdr *gh; struct gsm48_loc_area_id *lai; @@ -490,8 +489,9 @@ gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT; lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); - gsm48_generate_lai(lai, bts->network->country_code, - bts->network->network_code, bts->location_area_code); + gsm48_generate_lai(lai, conn->network->country_code, + conn->network->network_code, + conn->bts->location_area_code); if (conn->subscr->tmsi == GSM_RESERVED_TMSI) { uint8_t mi[10]; @@ -506,7 +506,7 @@ DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n"); - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_ACCEPT]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_RESP_ACCEPT]); return gsm48_conn_sendmsg(msg, conn, NULL); } @@ -543,9 +543,7 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm_lchan *lchan = msg->lchan; - struct gsm_bts *bts = lchan->ts->trx->bts; - struct gsm_network *net = bts->network; + struct gsm_network *net = conn->network; uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; char mi_string[GSM48_MI_SIZE]; @@ -565,7 +563,7 @@ conn->subscr = subscr_create(net, mi_string); } if (!conn->subscr && conn->loc_operation) { - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, net->reject_cause); release_loc_updating_req(conn, 1); return 0; } @@ -592,11 +590,9 @@ static void loc_upd_rej_cb(void *data) { struct gsm_subscriber_connection *conn = data; - struct gsm_lchan *lchan = conn->lchan; - struct gsm_bts *bts = lchan->ts->trx->bts; LOGP(DMM, LOGL_DEBUG, "Location Updating Request procedure timedout.\n"); - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, conn->network->reject_cause); release_loc_updating_req(conn, 1); } @@ -620,7 +616,6 @@ struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_loc_upd_req *lu; struct gsm_subscriber *subscr = NULL; - struct gsm_bts *bts = conn->bts; uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; @@ -637,13 +632,13 @@ switch (lu->type) { case GSM48_LUPD_NORMAL: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); break; case GSM48_LUPD_IMSI_ATT: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); break; case GSM48_LUPD_PERIODIC: - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); break; } @@ -670,12 +665,11 @@ conn->loc_operation->waiting_for_imei = 1; /* look up subscriber based on IMSI, create if not found */ - subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string); + subscr = subscr_get_by_imsi(conn->network->subscr_group, mi_string); if (!subscr) - subscr = subscr_create(bts->network, mi_string); - + subscr = subscr_create(conn->network, mi_string); if (!subscr) { - gsm0408_loc_upd_rej(conn, bts->network->reject_cause); + gsm0408_loc_upd_rej(conn, conn->network->reject_cause); release_loc_updating_req(conn, 0); return 0; } @@ -683,7 +677,7 @@ case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); /* look up the subscriber based on TMSI, request IMSI if it fails */ - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(conn->network->subscr_group, tmsi_from_string(mi_string)); if (!subscr) { /* send IDENTITY REQUEST message to get IMSI */ @@ -738,7 +732,7 @@ { struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF"); struct gsm48_hdr *gh; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_bts *bts = conn->bts; uint8_t *ptr8; int name_len, name_pad; @@ -973,7 +967,7 @@ uint8_t mi_type; char mi_string[GSM48_MI_SIZE]; - struct gsm_bts *bts = conn->bts; + struct gsm_network *network = conn->network; struct gsm_subscriber *subscr; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_service_request *req = @@ -1004,13 +998,13 @@ DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", req->cm_service_type, gsm48_mi_type_name(mi_type), mi_string); - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(network->subscr_group, mi_string); } else if (mi_type == GSM_MI_TYPE_TMSI) { DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", req->cm_service_type, gsm48_mi_type_name(mi_type), mi_string); - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(network->subscr_group, tmsi_from_string(mi_string)); } else { DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type); @@ -1020,7 +1014,7 @@ osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len)); - if (is_siemens_bts(bts)) + if (is_siemens_bts(conn->bts)) send_siemens_mrpci(msg->lchan, classmark2-1); @@ -1051,7 +1045,7 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct gsm_bts *bts = conn->bts; + struct gsm_network *network = conn->network; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_imsi_detach_ind *idi = (struct gsm48_imsi_detach_ind *) gh->data; @@ -1063,17 +1057,17 @@ DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s", gsm48_mi_type_name(mi_type), mi_string); - rate_ctr_inc(&bts->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); + rate_ctr_inc(&network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); switch (mi_type) { case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(network->subscr_group, tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: DEBUGPC(DMM, "\n"); - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(network->subscr_group, mi_string); break; case GSM_MI_TYPE_IMEI: @@ -1087,7 +1081,7 @@ } if (subscr) { - subscr_update(subscr, bts, + subscr_update(subscr, conn->bts, GSM_SUBSCRIBER_UPDATE_DETACHED); DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr)); @@ -1119,7 +1113,7 @@ { struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; DEBUGP(DMM, "MM AUTHENTICATION RESPONSE (sres = %s): ", osmo_hexdump(ar->sres, 4)); @@ -1200,7 +1194,6 @@ /* Receive a PAGING RESPONSE message from the MS */ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct gsm_bts *bts = conn->bts; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_pag_resp *resp; uint8_t *classmark2_lv = gh->data + 1; @@ -1217,11 +1210,11 @@ switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(bts->network->subscr_group, + subscr = subscr_get_by_tmsi(conn->network->subscr_group, tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: - subscr = subscr_get_by_imsi(bts->network->subscr_group, + subscr = subscr_get_by_imsi(conn->network->subscr_group, mi_string); break; } @@ -3595,7 +3588,7 @@ DEBUGP(DCC, "Unknown transaction ID %x, " "creating new trans.\n", transaction_id); /* Create transaction */ - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_CC, transaction_id, new_callref++); if (!trans) { diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 08d8fdf..3a2effe 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -309,20 +309,20 @@ #endif /* determine gsms->receiver based on dialled number */ - gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group, + gsms->receiver = subscr_get_by_extension(conn->network->subscr_group, gsms->dst.addr); if (!gsms->receiver) { #ifdef BUILD_SMPP /* Avoid a second look-up */ if (smpp_first) { - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); return 1; /* cause 1: unknown subscriber */ } rc = smpp_try_deliver(gsms, conn); if (rc == 1) { rc = 1; /* cause 1: unknown subscriber */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); } else if (rc < 0) { LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", subscr_name(conn->subscr), rc); @@ -333,7 +333,7 @@ } #else rc = 1; /* cause 1: unknown subscriber */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); #endif return rc; } @@ -374,7 +374,7 @@ uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */ int rc = 0; - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); gsms = sms_alloc(); if (!gsms) @@ -616,7 +616,7 @@ static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, struct gsm411_rp_hdr *rph) { - struct gsm_network *net = trans->conn->bts->network; + struct gsm_network *net = trans->conn->network; struct gsm_sms *sms = trans->sms.sms; uint8_t cause_len = rph->data[0]; uint8_t cause = rph->data[1]; @@ -816,7 +816,7 @@ if (!trans) { DEBUGP(DLSMS, " -> (new transaction)\n"); - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_SMS, transaction_id, new_callref++); if (!trans) { @@ -878,7 +878,7 @@ int rc; transaction_id = - trans_assign_trans_id(conn->bts->network, conn->subscr, + trans_assign_trans_id(conn->network, conn->subscr, GSM48_PDISC_SMS, 0); if (transaction_id == -1) { LOGP(DLSMS, LOGL_ERROR, "No available transaction ids\n"); @@ -891,7 +891,7 @@ DEBUGP(DLSMS, "%s()\n", __func__); /* FIXME: allocate transaction with message reference */ - trans = trans_alloc(conn->bts->network, conn->subscr, + trans = trans_alloc(conn->network, conn->subscr, GSM48_PDISC_SMS, transaction_id, new_callref++); if (!trans) { @@ -943,7 +943,7 @@ DEBUGP(DLSMS, "TX: SMS DELIVER\n"); - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); + rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); db_sms_inc_deliver_attempts(trans->sms.sms); return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, @@ -1037,7 +1037,7 @@ struct gsm_network *net; struct gsm_trans *trans, *tmp; - net = conn->bts->network; + net = conn->network; llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) { struct gsm_sms *sms; diff --git a/openbsc/src/libmsc/rrlp.c b/openbsc/src/libmsc/rrlp.c index 161456a..e695daa 100644 --- a/openbsc/src/libmsc/rrlp.c +++ b/openbsc/src/libmsc/rrlp.c @@ -40,7 +40,7 @@ static int send_rrlp_req(struct gsm_subscriber_connection *conn) { - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; const uint8_t *req; switch (net->rrlp.mode) { diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c index a750362..dba4bed 100644 --- a/openbsc/src/libmsc/transaction.c +++ b/openbsc/src/libmsc/transaction.c @@ -37,7 +37,7 @@ uint8_t proto, uint8_t trans_id) { struct gsm_trans *trans; - struct gsm_network *net = conn->bts->network; + struct gsm_network *net = conn->network; struct gsm_subscriber *subscr = conn->subscr; llist_for_each_entry(trans, &net->trans_list, entry) { @@ -155,7 +155,7 @@ { struct gsm_trans *trans; - llist_for_each_entry(trans, &conn->bts->network->trans_list, entry) + llist_for_each_entry(trans, &conn->network->trans_list, entry) if (trans->conn == conn) return 1; -- To view, visit https://gerrit.osmocom.org/927 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I34537025986713291e14c8212a81539b497befd4 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:22 +0000 Subject: [MERGED] openbsc[master]: mscsplit: add gsm_network backpointer to gsm_subscriber_conn... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: add gsm_network backpointer to gsm_subscriber_connection ...................................................................... mscsplit: add gsm_network backpointer to gsm_subscriber_connection We want to be able to use a network backpointer without having to go through a gsm_bts struct. This commit adds the network pointer, the subsequent commit applies direct access to the network structure from gsm_subscriber_connection. Change-Id: If8870972f1b3e333c2a4cce97cdc95bdee0382a1 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c 2 files changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 26efeaa..ffb7dd2 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -134,6 +134,8 @@ struct osmo_bsc_sccp_con *sccp_con; /* back pointers */ + struct gsm_network *network; + int in_release; struct gsm_lchan *lchan; struct gsm_lchan *ho_lchan; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index f42598a..02751f4 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -247,6 +247,7 @@ if (!conn) return NULL; + conn->network = net; conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; -- To view, visit https://gerrit.osmocom.org/926 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If8870972f1b3e333c2a4cce97cdc95bdee0382a1 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:22 +0000 Subject: [MERGED] openbsc[master]: mscsplit: abis vty: decouple from global bsc_gsmnet variable In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: abis vty: decouple from global bsc_gsmnet variable ...................................................................... mscsplit: abis vty: decouple from global bsc_gsmnet variable Publish gsmnet_from_vty() in openbsc/vty.h and use in the abis VTY functions. Change-Id: Ib65a18db06b8bc4fc7d56bf56dd64a52cc1cd253 --- M openbsc/include/openbsc/vty.h M openbsc/src/libbsc/abis_nm_vty.c M openbsc/src/libbsc/abis_om2000_vty.c 3 files changed, 6 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index 78e87f0..315db0d 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -46,4 +46,6 @@ int bsc_vty_init(const struct log_info *cat, struct gsm_network *network); int bsc_vty_init_extra(void); +struct gsm_network *gsmnet_from_vty(struct vty *vty); + #endif diff --git a/openbsc/src/libbsc/abis_nm_vty.c b/openbsc/src/libbsc/abis_nm_vty.c index a14e5c2..6ec0a4a 100644 --- a/openbsc/src/libbsc/abis_nm_vty.c +++ b/openbsc/src/libbsc/abis_nm_vty.c @@ -94,7 +94,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -128,7 +128,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; diff --git a/openbsc/src/libbsc/abis_om2000_vty.c b/openbsc/src/libbsc/abis_om2000_vty.c index 8325e29..72422a1 100644 --- a/openbsc/src/libbsc/abis_om2000_vty.c +++ b/openbsc/src/libbsc/abis_om2000_vty.c @@ -82,7 +82,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -122,7 +122,7 @@ struct oml_node_state *oms; int bts_nr = atoi(argv[0]); - bts = gsm_bts_num(bsc_gsmnet, bts_nr); + bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr); if (!bts) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; -- To view, visit https://gerrit.osmocom.org/925 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib65a18db06b8bc4fc7d56bf56dd64a52cc1cd253 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:22 +0000 Subject: [MERGED] openbsc[master]: mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet ...................................................................... mscsplit: bsc_vty_init(): decouple from global bsc_gsmnet Add an explicit gsm_network pointer instead of using the bsc_gsmnet global. This allows passing a gsm_network struct from the main() scope, which helps to decouple libmsc from libbsc. Change-Id: I9e2c0d9c18d4cebb5efb71565ad84df2bc2e0251 --- M openbsc/include/openbsc/vty.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/osmo-bsc/osmo_bsc_main.c M openbsc/src/osmo-bsc_nat/bsc_nat_vty.c M openbsc/src/osmo-nitb/bsc_hack.c 5 files changed, 5 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index bc30e23..78e87f0 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -43,7 +43,7 @@ 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); #endif diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 01eec23..cdcc011 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -4028,7 +4028,7 @@ extern int bsc_vty_init_extra(void); -int bsc_vty_init(const struct log_info *cat) +int bsc_vty_init(const struct log_info *cat, struct gsm_network *network) { cfg_ts_pchan_cmd.string = vty_cmd_string_from_valstr(tall_bsc_ctx, diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 3594a5b..2ee5fb4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -204,7 +204,7 @@ /* This needs to precede handle_options() */ vty_info.copyright = openbsc_copyright; vty_init(&vty_info); - bsc_vty_init(&log_info); + bsc_vty_init(&log_info, bsc_gsmnet); bsc_msg_lst_vty_init(tall_bsc_ctx, &access_lists, BSC_NODE); ctrl_vty_init(tall_bsc_ctx); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c index 3708bc2..706e507 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c @@ -1329,7 +1329,7 @@ /* called by the telnet interface... we have our own init above */ -int bsc_vty_init(const struct log_info *cat) +int bsc_vty_init(const struct log_info *cat, struct gsm_network *network) { logging_vty_add_cmds(cat); return 0; diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 67efe4f..8e1ddae 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -271,7 +271,7 @@ /* This needs to precede handle_options() */ vty_init(&vty_info); - bsc_vty_init(&log_info); + bsc_vty_init(&log_info, bsc_gsmnet); ctrl_vty_init(tall_bsc_ctx); #ifdef BUILD_SMPP -- To view, visit https://gerrit.osmocom.org/924 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9e2c0d9c18d4cebb5efb71565ad84df2bc2e0251 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:23 +0000 Subject: [MERGED] openbsc[master]: mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx ...................................................................... mscsplit: talloc_ctx_init(): decouple from global tall_bsc_ctx Decouple the talloc context allocations from global tall_bsc_ctx pointer. It appears that talloc_ctx_init() was intended for general use, since it is located in libcommon. It is currently used only by osmo-nitb; but the upcoming osmo-cscn will use it as well. Instead of defining in osmo-nitb main file, add definition in gsm_data.h. Change-Id: I168106599b788f586be0ff0af4699b9746c1b103 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libcommon/talloc_ctx.c M openbsc/src/osmo-nitb/bsc_hack.c 3 files changed, 19 insertions(+), 20 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index fbb0356..26efeaa 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -394,6 +394,8 @@ char text[SMS_TEXT_SIZE]; }; +extern void talloc_ctx_init(void *ctx_root); + struct gsm_network *gsm_network_init(void *ctx, uint16_t country_code, uint16_t network_code, diff --git a/openbsc/src/libcommon/talloc_ctx.c b/openbsc/src/libcommon/talloc_ctx.c index 528d3a2..a917a8c 100644 --- a/openbsc/src/libcommon/talloc_ctx.c +++ b/openbsc/src/libcommon/talloc_ctx.c @@ -36,22 +36,21 @@ extern void *tall_upq_ctx; extern void *tall_ctr_ctx; -void talloc_ctx_init(void) +void talloc_ctx_init(void *ctx_root) { - tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb"); - tall_fle_ctx = talloc_named_const(tall_bsc_ctx, 0, - "bs11_file_list_entry"); - tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 0, "loc_updating_oper"); - tall_authciphop_ctx = talloc_named_const(tall_bsc_ctx, 0, "auth_ciph_oper"); - tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 0, "sms"); - tall_subscr_ctx = talloc_named_const(tall_bsc_ctx, 0, "subscriber"); - tall_sub_req_ctx = talloc_named_const(tall_bsc_ctx, 0, "subscr_request"); - tall_call_ctx = talloc_named_const(tall_bsc_ctx, 0, "gsm_call"); - tall_paging_ctx = talloc_named_const(tall_bsc_ctx, 0, "paging_request"); - tall_sigh_ctx = talloc_named_const(tall_bsc_ctx, 0, "signal_handler"); - tall_tqe_ctx = talloc_named_const(tall_bsc_ctx, 0, "subch_txq_entry"); - tall_trans_ctx = talloc_named_const(tall_bsc_ctx, 0, "transaction"); - tall_map_ctx = talloc_named_const(tall_bsc_ctx, 0, "trau_map_entry"); - tall_upq_ctx = talloc_named_const(tall_bsc_ctx, 0, "trau_upq_entry"); - tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter"); + tall_msgb_ctx = talloc_named_const(ctx_root, 0, "msgb"); + tall_fle_ctx = talloc_named_const(ctx_root, 0, "bs11_file_list_entry"); + tall_locop_ctx = talloc_named_const(ctx_root, 0, "loc_updating_oper"); + tall_authciphop_ctx = talloc_named_const(ctx_root, 0, "auth_ciph_oper"); + tall_gsms_ctx = talloc_named_const(ctx_root, 0, "sms"); + tall_subscr_ctx = talloc_named_const(ctx_root, 0, "subscriber"); + tall_sub_req_ctx = talloc_named_const(ctx_root, 0, "subscr_request"); + tall_call_ctx = talloc_named_const(ctx_root, 0, "gsm_call"); + tall_paging_ctx = talloc_named_const(ctx_root, 0, "paging_request"); + tall_sigh_ctx = talloc_named_const(ctx_root, 0, "signal_handler"); + tall_tqe_ctx = talloc_named_const(ctx_root, 0, "subch_txq_entry"); + tall_trans_ctx = talloc_named_const(ctx_root, 0, "transaction"); + tall_map_ctx = talloc_named_const(ctx_root, 0, "trau_map_entry"); + tall_upq_ctx = talloc_named_const(ctx_root, 0, "trau_upq_entry"); + tall_ctr_ctx = talloc_named_const(ctx_root, 0, "counter"); } diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 976aefa..67efe4f 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -243,8 +243,6 @@ osmo_timer_schedule(&bsc_gsmnet->subscr_expire_timer, EXPIRE_INTERVAL); } -void talloc_ctx_init(void); - extern int bsc_vty_go_parent(struct vty *vty); static struct vty_app_info vty_info = { @@ -261,7 +259,7 @@ vty_info.copyright = openbsc_copyright; tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc"); - talloc_ctx_init(); + talloc_ctx_init(tall_bsc_ctx); on_dso_load_token(); on_dso_load_rrlp(); on_dso_load_ho_dec(); -- To view, visit https://gerrit.osmocom.org/923 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I168106599b788f586be0ff0af4699b9746c1b103 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:23 +0000 Subject: [MERGED] openbsc[master]: mscsplit: gsm_network_init(): add explicit root talloc ctx In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: gsm_network_init(): add explicit root talloc ctx ...................................................................... mscsplit: gsm_network_init(): add explicit root talloc ctx Decouple the root talloc context from libbsc's global talloc_bsc_ctx. This allows to define the root talloc ctx from a main() scope, which in turn helps decouple libmsc from libbsc. Change-Id: I92f6b47b1eeea2e8f3fba66f25d7e708e5659f8a --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/bsc_init.c M openbsc/src/libbsc/net_init.c M openbsc/src/utils/bs11_config.c M openbsc/tests/channel/channel_test.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 14 insertions(+), 9 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 07db02f..fbb0356 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -394,8 +394,11 @@ char text[SMS_TEXT_SIZE]; }; -struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code, +struct gsm_network *gsm_network_init(void *ctx, + 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); /* Get reference to a neighbor cell on a given BCCH ARFCN */ diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 31da056..9e3a471 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -983,7 +983,7 @@ } libosmo_abis_init(tall_ctx_config); - bsc_gsmnet = gsm_network_init(1, 1, NULL); + bsc_gsmnet = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); if (!bsc_gsmnet) exit(1); diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 371ddee..06f4121 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -477,7 +477,7 @@ int rc; /* initialize our data structures */ - bsc_gsmnet = gsm_network_init(1, 1, mncc_recv); + bsc_gsmnet = gsm_network_init(tall_bsc_ctx, 1, 1, mncc_recv); if (!bsc_gsmnet) return -ENOMEM; diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index e01ba80..e53b466 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -23,13 +23,15 @@ #include -struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code, +struct gsm_network *gsm_network_init(void *ctx, + uint16_t country_code, + uint16_t network_code, int (*mncc_recv)(struct gsm_network *, struct msgb *)) { struct gsm_network *net; const char *default_regexp = ".*"; - net = talloc_zero(tall_bsc_ctx, struct gsm_network); + net = talloc_zero(ctx, struct gsm_network); if (!net) return NULL; diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c index 3fb74bf..227b9f8 100644 --- a/openbsc/src/utils/bs11_config.c +++ b/openbsc/src/utils/bs11_config.c @@ -894,7 +894,7 @@ handle_options(argc, argv); bts_model_bs11_init(); - gsmnet = gsm_network_init(1, 1, NULL); + gsmnet = gsm_network_init(tall_bs11cfg_ctx, 1, 1, NULL); if (!gsmnet) { fprintf(stderr, "Unable to allocate gsm network\n"); exit(1); diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 5674607..924d763 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -68,7 +68,7 @@ printf("Testing the gsm_subscriber chan logic\n"); /* Create a dummy network */ - network = gsm_network_init(1, 1, NULL); + network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); if (!network) exit(1); bts = gsm_bts_alloc(network); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 7acc93f..e81394f 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -122,7 +122,7 @@ static inline void test_si2q_u(void) { struct gsm_bts *bts; - struct gsm_network *network = gsm_network_init(1, 1, NULL); + struct gsm_network *network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater UARFCN generation:\n"); if (!network) @@ -149,7 +149,7 @@ static inline void test_si2q_e(void) { struct gsm_bts *bts; - struct gsm_network *network = gsm_network_init(1, 1, NULL); + struct gsm_network *network = gsm_network_init(tall_bsc_ctx, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater EARFCN generation:\n"); if (!network) -- To view, visit https://gerrit.osmocom.org/922 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I92f6b47b1eeea2e8f3fba66f25d7e708e5659f8a Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:23 +0000 Subject: [MERGED] openbsc[master]: mscsplit: move subscriber conns list into struct gsm_network In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: move subscriber conns list into struct gsm_network ...................................................................... mscsplit: 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(), callers now access gsm_network->subscr_conns directly. This allows using the subscr_conns from libmsc without having to link libbsc. Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c --- M openbsc/include/openbsc/bsc_api.h M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_api.c M openbsc/src/libbsc/net_init.c M openbsc/src/osmo-bsc/osmo_bsc_ctrl.c 5 files changed, 8 insertions(+), 10 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h index a3d12f2..3a93119 100644 --- a/openbsc/include/openbsc/bsc_api.h +++ b/openbsc/include/openbsc/bsc_api.h @@ -52,6 +52,4 @@ 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 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 9317717..07db02f 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -345,6 +345,9 @@ /* Allow or disallow TCH/F on dynamic TCH/F_TCH/H_PDCH; OS#1778 */ bool dyn_ts_allow_tch_f; /* TODO: vty for this; related: OS#1781 */ + + /* all active subscriber connections. */ + struct llist_head subscr_conns; }; struct osmo_esme; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 8c830a3..f42598a 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -39,7 +39,6 @@ #define GSM0808_T10_VALUE 6, 0 -static LLIST_HEAD(sub_connections); static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind); static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id); @@ -242,15 +241,16 @@ struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan) { struct gsm_subscriber_connection *conn; + struct gsm_network *net = lchan->ts->trx->bts->network; - conn = talloc_zero(lchan->ts->trx->bts->network, struct gsm_subscriber_connection); + conn = talloc_zero(net, struct gsm_subscriber_connection); if (!conn) return NULL; conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; lchan->conn = conn; - llist_add_tail(&conn->entry, &sub_connections); + llist_add_tail(&conn->entry, &net->subscr_conns); return conn; } @@ -876,7 +876,3 @@ osmo_signal_register_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL); } -struct llist_head *bsc_api_sub_connections(struct gsm_network *net) -{ - return &sub_connections; -} diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 65419ae..e01ba80 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -79,6 +79,7 @@ INIT_LLIST_HEAD(&net->trans_list); INIT_LLIST_HEAD(&net->upqueue); INIT_LLIST_HEAD(&net->bts_list); + INIT_LLIST_HEAD(&net->subscr_conns); /* init statistics */ net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c index 72f80ed..3010b55 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c @@ -583,7 +583,7 @@ alert = atoi(alert_str); net = cmd->node; - llist_for_each_entry(conn, bsc_api_sub_connections(net), entry) { + llist_for_each_entry(conn, &net->subscr_conns, entry) { if (!conn->sccp_con) continue; -- To view, visit https://gerrit.osmocom.org/921 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:34:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:34:23 +0000 Subject: [MERGED] openbsc[master]: mscsplit: bsc_init: don't pass telnet dummy conn In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: mscsplit: bsc_init: don't pass telnet dummy conn ...................................................................... mscsplit: bsc_init: don't pass telnet dummy conn We want to create the telnet for VTY only after reading the config file, and the dummy_conn was a workaround to be able to do so, but is not needed: gsmnet_from_vty() used to expect vty->priv to point to a gsm_network struct, but that is not actually the case anymore. It is using a static pointer to store the gsm_network struct instead. Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 --- M openbsc/src/libbsc/bsc_init.c 1 file changed, 1 insertion(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 989fca8..371ddee 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -473,7 +473,6 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *), const char *config_file) { - struct telnet_connection dummy_conn; struct gsm_bts *bts; int rc; @@ -485,9 +484,7 @@ bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC"); bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC"); - /* our vty command code expects vty->priv to point to a telnet_connection */ - dummy_conn.priv = bsc_gsmnet; - rc = vty_read_config_file(config_file, &dummy_conn); + rc = vty_read_config_file(config_file, NULL); if (rc < 0) { LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file); return rc; -- To view, visit https://gerrit.osmocom.org/920 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I51e7224c5a4cd5baf564bee871cf2fa6e885cda7 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:35:24 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:35:24 +0000 Subject: libosmocore[master]: Fix ASAN failure in bitrev_test In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:35:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:35:31 +0000 Subject: [MERGED] libosmocore[master]: Fix ASAN failure in bitrev_test In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: Fix ASAN failure in bitrev_test ...................................................................... Fix ASAN failure in bitrev_test Previously while testing osmo_nibble_shift_left_unal() following error was triggered by AddressSanitizer upon offs == 12 and the last sh_chk line, i.e. shift left of 12 nibbles from in2: ==3890== ERROR: AddressSanitizer: stack-buffer-overflow on address 0xbff5b5b6 at pc 0xb6186862 bp 0xbff5b4a8 sp 0xbff5b49c READ of size 1 at 0xbff5b5b6 thread T0 #0 0xb6186861 (/home/msuraev/source/gsm/libosmocore/src/.libs/libosmocore.so.7.0.0+0xc861) #1 0x8049d8b (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8049d8b) #2 0x804a9d1 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x804a9d1) #3 0xb5fe3af2 (/lib/i386-linux-gnu/libc-2.19.so+0x19af2) #4 0x8048a30 (/home/msuraev/source/gsm/libosmocore/tests/bits/.libs/lt-bitrev_test+0x8048a30) Address 0xbff5b5b6 is located at offset 38 in frame
of T0's stack: This frame has 3 object(s): [32, 38) 'in2' [96, 104) 'out' [160, 168) 'in1' The reason is incorrect range in test cycle. Fix it and adjust test output accordingly. Tweaked-by: Neels Hofmeyr Fixes: OW#1589 ("undefined behavior in libosmocore triggered by tests") Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 3 insertions(+), 3 deletions(-) Approvals: Max: Looks good to me, but someone else must approve Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index 08f0827..b96241c 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -297,7 +297,9 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + /* in2 is too short to shift left 12 nibbles */ + if (offs < 12) + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index 9fbb4d9..e6f52af 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,5 +156,3 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac -[6] L IN: b00bbabeface, nibble 12: - OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/863 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5eb3f600290c05b4ab9ac2450a28d616e6b415fd Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:35:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:35:31 +0000 Subject: [MERGED] libosmocore[master]: bitrev_test: don't omit last byte from test result check In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: bitrev_test: don't omit last byte from test result check ...................................................................... bitrev_test: don't omit last byte from test result check The osmo_hexdump of the output in sh_chk() omitted the last byte of the returned bytes from the osmo_nibble_shift_*() functions. Determine the number of bytes from nibbles divided by two plus one for any odd nibble number. Output this number of bytes of output data. Memset the output buffer to get well-defined bytes for unwritten places. Also assert that we have enough buffer length for all nibbles. Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 28 insertions(+), 25 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index b96241c..ed3939a 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -208,6 +208,9 @@ static void sh_chk(const uint8_t *in, uint8_t len, unsigned int nib, bool r) { uint8_t x[len]; + int bytes = nib/2 + (nib & 1); + OSMO_ASSERT(len >= bytes); + memset(x, 0xcc, len); if (r) osmo_nibble_shift_right(x, in, nib); else @@ -217,7 +220,7 @@ osmo_hexdump_nospc(in, len), nib); /* do NOT combine those printfs: osmo_hexdump* use static buffer which WILL screw things up in that case */ - printf("\n OUT: %s\n", osmo_hexdump_nospc(x, nib/2)); + printf("\n OUT: %s\n", osmo_hexdump_nospc(x, bytes)); } int main(int argc, char **argv) diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index e6f52af..d2fb12c 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -63,13 +63,13 @@ [6] L IN: b00bbabeface, nibble 0: OUT: [8] R IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [8] L IN: f00dcafedeadbeef, nibble 1: - OUT: + OUT: cc [6] R IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [6] L IN: b00bbabeface, nibble 1: - OUT: + OUT: cc [8] R IN: f00dcafedeadbeef, nibble 2: OUT: 0f [8] L IN: f00dcafedeadbeef, nibble 2: @@ -79,13 +79,13 @@ [6] L IN: b00bbabeface, nibble 2: OUT: 00 [8] R IN: f00dcafedeadbeef, nibble 3: - OUT: 0f + OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 3: - OUT: 00 + OUT: 00d0 [6] R IN: b00bbabeface, nibble 3: - OUT: 0b + OUT: 0b00 [6] L IN: b00bbabeface, nibble 3: - OUT: 00 + OUT: 00b0 [8] R IN: f00dcafedeadbeef, nibble 4: OUT: 0f00 [8] L IN: f00dcafedeadbeef, nibble 4: @@ -95,13 +95,13 @@ [6] L IN: b00bbabeface, nibble 4: OUT: 00bb [8] R IN: f00dcafedeadbeef, nibble 5: - OUT: 0f00 + OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 5: - OUT: 00dc + OUT: 00dca0 [6] R IN: b00bbabeface, nibble 5: - OUT: 0b00 + OUT: 0b00bb [6] L IN: b00bbabeface, nibble 5: - OUT: 00bb + OUT: 00bba0 [8] R IN: f00dcafedeadbeef, nibble 6: OUT: 0f00dc [8] L IN: f00dcafedeadbeef, nibble 6: @@ -111,13 +111,13 @@ [6] L IN: b00bbabeface, nibble 6: OUT: 00bbab [8] R IN: f00dcafedeadbeef, nibble 7: - OUT: 0f00dc + OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 7: - OUT: 00dcaf + OUT: 00dcafe0 [6] R IN: b00bbabeface, nibble 7: - OUT: 0b00bb + OUT: 0b00bbab [6] L IN: b00bbabeface, nibble 7: - OUT: 00bbab + OUT: 00bbabe0 [8] R IN: f00dcafedeadbeef, nibble 8: OUT: 0f00dcaf [8] L IN: f00dcafedeadbeef, nibble 8: @@ -127,13 +127,13 @@ [6] L IN: b00bbabeface, nibble 8: OUT: 00bbabef [8] R IN: f00dcafedeadbeef, nibble 9: - OUT: 0f00dcaf + OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 9: - OUT: 00dcafed + OUT: 00dcafede0 [6] R IN: b00bbabeface, nibble 9: - OUT: 0b00bbab + OUT: 0b00bbabef [6] L IN: b00bbabeface, nibble 9: - OUT: 00bbabef + OUT: 00bbabefa0 [8] R IN: f00dcafedeadbeef, nibble 10: OUT: 0f00dcafed [8] L IN: f00dcafedeadbeef, nibble 10: @@ -143,13 +143,13 @@ [6] L IN: b00bbabeface, nibble 10: OUT: 00bbabefac [8] R IN: f00dcafedeadbeef, nibble 11: - OUT: 0f00dcafed + OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 11: - OUT: 00dcafedea + OUT: 00dcafedead0 [6] R IN: b00bbabeface, nibble 11: - OUT: 0b00bbabef + OUT: 0b00bbabefac [6] L IN: b00bbabeface, nibble 11: - OUT: 00bbabefac + OUT: 00bbabeface0 [8] R IN: f00dcafedeadbeef, nibble 12: OUT: 0f00dcafedea [8] L IN: f00dcafedeadbeef, nibble 12: -- To view, visit https://gerrit.osmocom.org/865 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I011f42bca555caec0dfe8688ff1f28303fa04fad Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 00:41:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 00:41:23 +0000 Subject: [PATCH] osmo-iuh[master]: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' In-Reply-To: References: Message-ID: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' The standard osmo VTY terminology is 'remote-ip', 'remote-port', 'local-ip', 'local-port'. Conform to that. osmo-hnbgw is so far not rolled out widely, so it makes sense to do this now. Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_vty.c 3 files changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/44/944/2 diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index dfe287c..dfc9d82 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -106,7 +106,7 @@ struct hnb_context *hnb; }; -#define HNBGW_IUH_BIND_ADDR_DEFAULT "0.0.0.0" +#define HNBGW_IUH_LOCAL_IP_DEFAULT "0.0.0.0" struct hnb_gw { struct { diff --git a/src/hnbgw.c b/src/hnbgw.c index d375e27..e44d872 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -312,7 +312,7 @@ { const char *addr = gw->config.iuh_bind_addr; if (!addr) - addr = HNBGW_IUH_BIND_ADDR_DEFAULT; + addr = HNBGW_IUH_LOCAL_IP_DEFAULT; return addr; } diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index d6fad64..5dee41a 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -105,9 +105,9 @@ return CMD_SUCCESS; } -DEFUN(cfg_hnbgw_iuh_bind, cfg_hnbgw_iuh_bind_cmd, "bind A.B.C.D", +DEFUN(cfg_hnbgw_iuh_local_ip, cfg_hnbgw_iuh_local_ip_cmd, "local-ip A.B.C.D", "Accept Iuh connections on local interface\n" - "Local interface IP address (default: " HNBGW_IUH_BIND_ADDR_DEFAULT ")") + "Local interface IP address (default: " HNBGW_IUH_LOCAL_IP_DEFAULT ")") { talloc_free((void*)g_hnb_gw->config.iuh_bind_addr); g_hnb_gw->config.iuh_bind_addr = talloc_strdup(tall_hnb_ctx, argv[0]); @@ -137,8 +137,8 @@ vty_out(vty, " iuh%s", VTY_NEWLINE); addr = g_hnb_gw->config.iuh_bind_addr; - if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0)) - vty_out(vty, " bind %s%s", addr, VTY_NEWLINE); + if (addr && (strcmp(addr, HNBGW_IUH_LOCAL_IP_DEFAULT) != 0)) + vty_out(vty, " local-ip %s%s", addr, VTY_NEWLINE); if (g_hnb_gw->config.hnbap_allow_tmsi) vty_out(vty, " hnbap-allow-tmsi 1%s", VTY_NEWLINE); @@ -159,7 +159,7 @@ install_node(&iuh_node, config_write_hnbgw_iuh); vty_install_default(IUH_NODE); - install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd); + install_element(IUH_NODE, &cfg_hnbgw_iuh_local_ip_cmd); install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd); install_element_ve(&show_hnb_cmd); -- To view, visit https://gerrit.osmocom.org/944 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 01:02:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 01:02:01 +0000 Subject: [PATCH] openbsc[master]: vty tests: nat_msc_test(): retry thrice for socket timeout Message-ID: Review at https://gerrit.osmocom.org/945 vty tests: nat_msc_test(): retry thrice for socket timeout The build server often hits below timeout by random, so let's give it three retries: ERROR: testBSCreload (__main__.TestVTYNAT) ---------------------------------------------------------------------- Traceback (most recent call last): File "./vty_test_runner.py", line 782, in testBSCreload msc = nat_msc_test(self, ip, port) File "./vty_test_runner.py", line 1237, in nat_msc_test conn, addr = msc.accept() File "/usr/lib/python2.7/socket.py", line 202, in accept sock, addr = self._sock.accept() timeout: timed out Change-Id: I8e1023f6ddd913f95402bb4afb8d02dccda17533 --- M openbsc/tests/vty_test_runner.py 1 file changed, 10 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/45/945/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 00eae70..cb6e1ed 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1233,8 +1233,17 @@ msc.listen(5) if (verbose): print "MSC is ready at " + ip + timeout_retries = 3; while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() + try: + conn, addr = msc.accept() + except socket.timeout: + # The build server hits this timeout every now and then. The + # timeout is long, but let's give it a couple of retries. + if timeout_retries < 1: + raise + timeout_retries -= 1 + continue if (verbose): print "MSC got connection from ", addr return conn -- To view, visit https://gerrit.osmocom.org/945 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8e1023f6ddd913f95402bb4afb8d02dccda17533 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 01:20:35 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 01:20:35 +0000 Subject: [PATCH] openbsc[master]: vty tests: testBSCreload: randomize port for msc In-Reply-To: References: Message-ID: vty tests: testBSCreload: randomize port for msc The build server often hits below timeout by random, so let's give it random ports and three retries: ERROR: testBSCreload (__main__.TestVTYNAT) ---------------------------------------------------------------------- Traceback (most recent call last): File "./vty_test_runner.py", line 782, in testBSCreload msc = nat_msc_test(self, ip, port) File "./vty_test_runner.py", line 1237, in nat_msc_test conn, addr = msc.accept() File "/usr/lib/python2.7/socket.py", line 202, in accept sock, addr = self._sock.accept() timeout: timed out Change-Id: I8e1023f6ddd913f95402bb4afb8d02dccda17533 --- M openbsc/tests/vty_test_runner.py 1 file changed, 17 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/45/945/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 00eae70..eecb5bf 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -19,6 +19,7 @@ import time import unittest import socket +import random import osmopy.obscvty as obscvty import osmopy.osmoutil as osmoutil @@ -752,10 +753,6 @@ return (4244, "src/osmo-bsc_nat/osmo-bsc_nat", "OsmoBSCNAT", "nat") def testBSCreload(self): - # Use different port for the mock msc to avoid clashing with - # the osmo-bsc_nat itself - ip = "127.0.0.1" - port = 5522 self.vty.enable() bscs1 = self.vty.command("show bscs-config") nat_bsc_reload(self) @@ -778,8 +775,22 @@ self.vty.command("token xyu") self.vty.command("end") - nat_msc_ip(self, ip, port) - msc = nat_msc_test(self, ip, port) + # Choose a random port for the mock msc to avoid clashing with the + # osmo-bsc_nat itself, and to reduce the chance of two test runs + # clashing on the build server. + timeout_retries = 3 + ip = "127.0.0.1" + while True: + port = random.randrange(32768, 65535) + try: + nat_msc_ip(self, ip, port) + msc = nat_msc_test(self, ip, port) + break + except socket.timeout: + timeout_retries -= 1 + if timeout_retries < 1: + raise + b0 = nat_bsc_sock_test(0, "lol") b1 = nat_bsc_sock_test(1, "xyu") b2 = nat_bsc_sock_test(5, "key") -- To view, visit https://gerrit.osmocom.org/945 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8e1023f6ddd913f95402bb4afb8d02dccda17533 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 01:20:35 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 01:20:35 +0000 Subject: [PATCH] openbsc[master]: cosmetic: vty_test_runner.py: add comment for vim auto settings Message-ID: Review at https://gerrit.osmocom.org/946 cosmetic: vty_test_runner.py: add comment for vim auto settings Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b --- M openbsc/tests/vty_test_runner.py 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/46/946/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index eecb5bf..334c62b 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1349,3 +1349,5 @@ add_sgsn_test(suite, workdir) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) + +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/946 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 01:44:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 01:44:48 +0000 Subject: openbsc[master]: mscsplit: move subscriber conns list into struct gsm_network In-Reply-To: References: Message-ID: Patch Set 2: These mscsplit commits were built successfully, and I merged them manually due to the "change is new" issue. However, after that, gerrit chose to retrigger the builds, probably due to a rebase. This is when most of these hit a timeout failure which I will hopefully fix in #945. I then aborted the remaining build jobs for the mscsplit commits. -- To view, visit https://gerrit.osmocom.org/921 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ice2a7ca04910bcfaaff22539abe68a6349e8631c Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 26 09:52:10 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 26 Sep 2016 09:52:10 +0000 Subject: libosmo-abis[master]: Remove use of private oRTP function In-Reply-To: References: Message-ID: Patch Set 1: I think this should be rised with upstream than - using private API might work for now but it can be changed at any time without notification which would lead to hard-to-find bugs. -- To view, visit https://gerrit.osmocom.org/908 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Sep 26 11:02:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 11:02:32 +0000 Subject: [PATCH] openbsc[master]: cosmetic: vty_test_runner.py: add comment for vim auto settings In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/946 to look at the new patch set (#2). cosmetic: vty_test_runner.py: add comment for vim auto settings Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b --- M openbsc/tests/vty_test_runner.py 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/46/946/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 00eae70..9fe4c3e 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1338,3 +1338,5 @@ add_sgsn_test(suite, workdir) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) + +# vim: set shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/946 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Sep 26 11:02:32 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 11:02:32 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: raise exception when MSC socket connecti... Message-ID: Review at https://gerrit.osmocom.org/947 vty_test_runner.py: raise exception when MSC socket connection fails Instead of below error, raise an exception to describe what's happening. Seen in a jenkins run on https://gerrit.osmocom.org/#/c/945/2: ERROR: testBSCreload (__main__.TestVTYNAT) ---------------------------------------------------------------------- Traceback (most recent call last): File "./vty_test_runner.py", line 787, in testBSCreload msc = nat_msc_test(self, ip, port) File "./vty_test_runner.py", line 1251, in nat_msc_test return conn UnboundLocalError: local variable 'conn' referenced before assignment Change-Id: Iae26e7345267a21aed0b108b089453832889c9fa --- M openbsc/tests/vty_test_runner.py 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/47/947/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 9fe4c3e..f624fc9 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1233,10 +1233,14 @@ msc.listen(5) if (verbose): print "MSC is ready at " + ip + conn = None while "MSC is connected: 0" == x.vty.command("show msc connection"): conn, addr = msc.accept() if (verbose): print "MSC got connection from ", addr + if not conn: + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): -- To view, visit https://gerrit.osmocom.org/947 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iae26e7345267a21aed0b108b089453832889c9fa Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 13:57:51 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 26 Sep 2016 13:57:51 +0000 Subject: [PATCH] libosmo-abis[master]: Unify RTP receiving Message-ID: Review at https://gerrit.osmocom.org/948 Unify RTP receiving * Remove code duplication * Use return value of rtp_get_payload() instead of pointer arithmetic Change-Id: Id42e85b55eab33c5eb81ac7a2cdea7962b2e30ef --- M src/trau/osmo_ortp.c 1 file changed, 18 insertions(+), 27 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/48/948/1 diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c index 5441337..b1d762c 100644 --- a/src/trau/osmo_ortp.c +++ b/src/trau/osmo_ortp.c @@ -142,6 +142,19 @@ "osmo-ortp(%d): timestamp_jump, new TS %d\n", port, ts); } +static inline bool recv_with_cb(struct osmo_rtp_socket *rs) +{ + mblk_t *mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); + if (!mblk) + return false; + + int plen = rtp_get_payload(mblk, &mblk->b_rptr); + /* hand into receiver */ + if (rs->rx_cb) + rs->rx_cb(rs, mblk->b_rptr, plen, rtp_get_markbit(mblk)); + freemsg(mblk); + return true; +} /*! \brief poll the socket for incoming data * \param[in] rs the socket to be polled @@ -149,26 +162,14 @@ */ int osmo_rtp_socket_poll(struct osmo_rtp_socket *rs) { - mblk_t *mblk; if (rs->flags & OSMO_RTP_F_DISABLED) return 0; - mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); - if (mblk) { - rtp_get_payload(mblk, &mblk->b_rptr); - /* hand into receiver */ - if (rs->rx_cb) - rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr, - rtp_get_markbit(mblk)); - //rs->rx_user_ts += 160; - freemsg(mblk); + if (recv_with_cb(rs)) return 1; - } else { - LOGP(DLMIB, LOGL_INFO, "osmo_rtp_poll(%u): ERROR!\n", - rs->rx_user_ts); - return 0; - } + + LOGP(DLMIB, LOGL_INFO, "osmo_rtp_poll(%u): ERROR!\n", rs->rx_user_ts); + return 0; } /* Osmo FD callbacks */ @@ -176,7 +177,6 @@ static int osmo_rtp_fd_cb(struct osmo_fd *fd, unsigned int what) { struct osmo_rtp_socket *rs = fd->data; - mblk_t *mblk; if (what & BSC_FD_READ) { /* in polling mode, we don't want to be called here */ @@ -184,16 +184,7 @@ fd->when &= ~BSC_FD_READ; return 0; } - mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts); - if (mblk) { - rtp_get_payload(mblk, &mblk->b_rptr); - /* hand into receiver */ - if (rs->rx_cb) - rs->rx_cb(rs, mblk->b_rptr, - mblk->b_wptr - mblk->b_rptr, - rtp_get_markbit(mblk)); - freemsg(mblk); - } else + if (!recv_with_cb(rs)) LOGP(DLMIB, LOGL_INFO, "recvm_with_ts(%u): ERROR!\n", rs->rx_user_ts); rs->rx_user_ts += 160; -- To view, visit https://gerrit.osmocom.org/948 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id42e85b55eab33c5eb81ac7a2cdea7962b2e30ef Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Mon Sep 26 14:32:20 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 26 Sep 2016 14:32:20 +0000 Subject: [PATCH] osmo-bts[master]: DTX: remove misleading comment Message-ID: Review at https://gerrit.osmocom.org/949 DTX: remove misleading comment There's no SID stored in UL direction so there's nothing to remove. Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15 --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/49/949/1 diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index e06c4cf..bcf981e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -412,7 +412,7 @@ goto err_payload_match; /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP - frame and drop last SID */ + frame */ lchan->rtp_tx_marker = true; break; case GsmL1_TchPlType_Amr_SidFirstP1: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index b1ab086..f350398 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -513,7 +513,7 @@ goto err_payload_match; /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP - frame and drop last SID */ + frame */ lchan->rtp_tx_marker = true; break; case GsmL1_TchPlType_Amr_SidFirstP1: -- To view, visit https://gerrit.osmocom.org/949 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Mon Sep 26 15:06:49 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Mon, 26 Sep 2016 15:06:49 +0000 Subject: [PATCH] openbsc[master]: SLHC: Improving slhc (RFC1144) testcase Message-ID: Review at https://gerrit.osmocom.org/950 SLHC: Improving slhc (RFC1144) testcase - Adding Testcases for UNCOMPRESSED_TCP and TYPE_IP - Minor cosmetic changes Change-Id: I555fa3c9b9f78424102f359ef1c27b290fa9c9e9 --- M openbsc/tests/slhc/slhc_test.c M openbsc/tests/slhc/slhc_test.ok 2 files changed, 130 insertions(+), 56 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/50/950/1 diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c index 59a5425..e8ea02f 100644 --- a/openbsc/tests/slhc/slhc_test.c +++ b/openbsc/tests/slhc/slhc_test.c @@ -38,14 +38,27 @@ #define DISP_MAX_BYTES 100 /* Sample packets to test with */ -#define PACKETS_LEN 6 +#define PACKETS_LEN 15 char *packets[] = { + /* With TCP Option 10 (Timestamps) in place (forces UNCOMPRESSED_TCP) */ "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", - "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20", + /* Regular TCP packets (COMPRESSED_TCP) */ + "4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27", + "4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01", + "4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01", + "4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20", + /* UDP packets (TYPE_IP */ + "450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001", + "450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e6b73c014c00c000200010000173d000603646e73c041c00c000200010000173d000a0767616e65736861c041c058000100010000173d0004d55f2e45c058001c00010000173d0010200107800045f0460000000000690001c06a0001000100006a710004d55f1b78c039000100010000173d000453ecb2cb", + "45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001", + "0050b6162c10000db93a3ff908004500004726a6000038114083080808080a0901650035ef1b00338a8cc3918180000100010000000006676f6f676c650264650000010001c00c000100010000012b0004d83ad503", }; /* Compress a packet using Van Jacobson RFC1144 header compression */ @@ -134,54 +147,13 @@ OSMO_ASSERT(len > 20); OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + printf("packet[9]=%02x\n", packet[9]); + /* Check TCP packet */ if (packet[9] != 0x06) return; OSMO_ASSERT(len > 40); OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); -} - -/* Strip TCP options from TCP/IP packet */ -static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) -{ - uint8_t doff; - uint16_t csum; - - /* Check if the packet can be handled here */ - if (len < 37) - return len; - if (packet[9] != 0x06) - return len; - - /* Strip TCP/IP options from packet */ - doff = ((packet[32] >> 4) & 0x0F) * 4; - memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); - len = len - (doff - 20); - - /* Repair data offset (TCP header length) */ - packet[32] &= 0x0F; - packet[32] |= 0x50; - - /* Repair checksum */ - packet[36] = 0; - packet[37] = 0; - csum = calc_tcpip_csum(ctx, packet, len); - packet[36] = csum & 0xFF; - packet[37] = csum >> 8 & 0xFF; - - /* Repair total length */ - packet[3] = len & 0xFF; - packet[2] = len >> 8 & 0xFF; - - /* Repair IP header checksum */ - packet[10] = 0; - packet[11] = 0; - csum = calc_ip_csum(packet, 20); - packet[10] = csum & 0xFF; - packet[11] = csum >> 8 & 0xFF; - printf("csum=%04x\n", csum); - - return len; } /* Compress / Decompress packets */ @@ -202,18 +174,18 @@ comp = slhc_init(ctx, SLOTS, SLOTS); OSMO_ASSERT(comp); - for(i=0;i From gerrit-no-reply at lists.osmocom.org Mon Sep 26 20:48:54 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 20:48:54 +0000 Subject: [PATCH] osmo-iuh[master]: log VTY telnet bind only once Message-ID: Review at https://gerrit.osmocom.org/951 log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: Icd9e670c1d30c156f7bd5d0d34892150aeba95e9 --- M src/hnbgw.c M src/tests/hnb-test.c 2 files changed, 0 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/51/951/1 diff --git a/src/hnbgw.c b/src/hnbgw.c index d50e622..8c860b1 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -474,8 +474,6 @@ log_set_log_level(osmo_stderr_target, hnbgw_cmdline_config.log_level); - LOGP(DMAIN, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), 2323); rc = telnet_init_dynif(NULL, g_hnb_gw, vty_get_bind_addr(), 2323); if (rc < 0) { perror("Error binding VTY port"); diff --git a/src/tests/hnb-test.c b/src/tests/hnb-test.c index d338077..68a3117 100644 --- a/src/tests/hnb-test.c +++ b/src/tests/hnb-test.c @@ -944,7 +944,6 @@ vty_init(&vty_info); hnbtest_vty_init(); - printf("VTY at %s %d\n", vty_get_bind_addr(), 2324); rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324); if (rc < 0) { perror("Error binding VTY port"); -- To view, visit https://gerrit.osmocom.org/951 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icd9e670c1d30c156f7bd5d0d34892150aeba95e9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 20:53:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 20:53:06 +0000 Subject: [PATCH] openbsc[master]: log VTY telnet bind only once Message-ID: Review at https://gerrit.osmocom.org/952 log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: I97a730b28759df1d549a5049f47a3da1c16a3447 --- M openbsc/src/gprs/gb_proxy_main.c M openbsc/src/gprs/gtphub_main.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/libbsc/bsc_init.c M openbsc/src/osmo-bsc_mgcp/mgcp_main.c M openbsc/src/osmo-bsc_nat/bsc_nat.c 6 files changed, 0 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/52/952/1 diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c index 0c3cfbe..2ddfca7 100644 --- a/openbsc/src/gprs/gb_proxy_main.c +++ b/openbsc/src/gprs/gb_proxy_main.c @@ -271,8 +271,6 @@ } /* 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) diff --git a/openbsc/src/gprs/gtphub_main.c b/openbsc/src/gprs/gtphub_main.c index 89582b1..1e20a63 100644 --- a/openbsc/src/gprs/gtphub_main.c +++ b/openbsc/src/gprs/gtphub_main.c @@ -325,8 +325,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DGTPHUB, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_GTPHUB); rc = telnet_init_dynif(osmo_gtphub_ctx, 0, vty_get_bind_addr(), OSMO_VTY_PORT_GTPHUB); if (rc < 0) diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index fb5b6d5..93848f5 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -382,8 +382,6 @@ } /* 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_SGSN); rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, vty_get_bind_addr(), OSMO_VTY_PORT_SGSN); if (rc < 0) diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 06f4121..c38bca1 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -491,8 +491,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_NITB_BSC); rc = telnet_init_dynif(tall_bsc_ctx, bsc_gsmnet, vty_get_bind_addr(), OSMO_VTY_PORT_NITB_BSC); if (rc < 0) diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c index e226b02..ac55e25 100644 --- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c +++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c @@ -233,8 +233,6 @@ return rc; /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DMGCP, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP); rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP); if (rc < 0) diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index f20b248..57cc8b3 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1639,8 +1639,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DNAT, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_BSC_NAT); if (telnet_init_dynif(tall_bsc_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_BSC_NAT)) { fprintf(stderr, "Creating VTY telnet line failed\n"); -- To view, visit https://gerrit.osmocom.org/952 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I97a730b28759df1d549a5049f47a3da1c16a3447 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Sep 26 20:56:35 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 26 Sep 2016 20:56:35 +0000 Subject: [PATCH] osmo-sip-connector[master]: log VTY telnet bind only once Message-ID: Review at https://gerrit.osmocom.org/953 log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: I7db7f7a2e61ba676c2712bcc149a5fd5a69b80b2 --- M src/main.c 1 file changed, 0 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/53/953/1 diff --git a/src/main.c b/src/main.c index ae4f20a..89706e3 100644 --- a/src/main.c +++ b/src/main.c @@ -135,8 +135,6 @@ exit(1); } - LOGP(DAPP, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_MNCC_SIP); rc = telnet_init_dynif(tall_mncc_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_MNCC_SIP); if (rc < 0) -- To view, visit https://gerrit.osmocom.org/953 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7db7f7a2e61ba676c2712bcc149a5fd5a69b80b2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 00:39:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 00:39:03 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs when build failed In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/866 to look at the new patch set (#4). jenkins.sh: output all test logs when build failed Assume that cat-testlogs.sh from buildserver-commons is in the PATH, and call from jenkins.sh upon 'make check' failure. Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- M contrib/jenkins.sh 1 file changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/4 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e9f63e4 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 00:39:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 00:39:03 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/871 to look at the new patch set (#4). NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac --- M tests/a5/a5_test.ok 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/71/871/4 diff --git a/tests/a5/a5_test.ok b/tests/a5/a5_test.ok index cefcdb6..9f7f9c3 100644 --- a/tests/a5/a5_test.ok +++ b/tests/a5/a5_test.ok @@ -10,6 +10,13 @@ A5/3 - UL: 001001010000100100000011011110001110000001010100000001000101011111000101011111100011011001110110011000101110010001 => OK A5/3 - DL: 000011100100000000010101011101010101101000110011011001000110100111000011110111011000011010000000111000110000001101 => OK A5/3 - UL: 011011110001000001100110100111100010101101001110000110001011000001000010010000110001101000101000111001000111111110 => OK + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + A5/3 - DL: 101010110111110110110011100010100101011100111010001100100101110110101010011101101110010011001011100000000000101001 => OK A5/3 - UL: 010011000100101101011001010011111110101010011101000000001111111010001001011110001011011110110111101111000001000010 => OK A5/3 - DL: 011101011111011111000100110001010001010101100000100100000101110111111011101000000101111001000110111110110101010011 => OK -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 00:44:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 00:44:42 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs when build failed In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/866 to look at the new patch set (#5). jenkins.sh: output all test logs when build failed Assume that cat-testlogs.sh from osmo-ci is installed in $HOME/osmo-ci/scripts, and call from jenkins.sh upon 'make check' failure. Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- M contrib/jenkins.sh 1 file changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/5 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e9f63e4 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 00:51:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 00:51:06 +0000 Subject: [PATCH] osmo-iuh[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/868 to look at the new patch set (#2). jenkins.sh: output all test logs when 'make check' failed Assume that cat-testlogs.sh from osmo-ci is installed in $HOME/osmo-ci/scripts, and call from jenkins.sh upon 'make check' failure. Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae --- M contrib/jenkins.sh 1 file changed, 5 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/68/868/2 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 8021bbd..b19f0c6 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex @@ -74,5 +75,7 @@ fi $MAKE $PARALLEL_MAKE -LD_LIBRARY_PATH="$inst/lib" $MAKE check -LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck +LD_LIBRARY_PATH="$inst/lib" $MAKE check \ + || cat-testlogs.sh +LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/868 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 00:51:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 00:51:06 +0000 Subject: [PATCH] osmo-iuh[master]: NOT FOR MERGE: testrun for cat-testlogs.sh: break a test exp... Message-ID: Review at https://gerrit.osmocom.org/954 NOT FOR MERGE: testrun for cat-testlogs.sh: break a test expectation Change-Id: I906d7547c055e7943323a472a982d3bbf9c36228 --- M src/tests/test-hnbap.ok 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/54/954/1 diff --git a/src/tests/test-hnbap.ok b/src/tests/test-hnbap.ok index 03331c4..00c67ad 100644 --- a/src/tests/test-hnbap.ok +++ b/src/tests/test-hnbap.ok @@ -1,4 +1,11 @@ Testing asn.1 HNBAP decoding HNBAP register request for HNB 10005B9-0010942050@ HNBAP UE Register request from IMSI 262011234567890 + + / .' + .---. \/ + (._.' \() + ^"""^" + bug + HNBAP UE Register accept to IMSI 262011234567890 -- To view, visit https://gerrit.osmocom.org/954 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I906d7547c055e7943323a472a982d3bbf9c36228 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:03:14 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:03:14 +0000 Subject: libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Patch Set 4: This failure shows that the cat-testlogs.sh script works, i.e. we see the bug in the console output. -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:03:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:03:38 +0000 Subject: osmo-iuh[master]: NOT FOR MERGE: testrun for cat-testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Patch Set 1: This failure shows that the cat-testlogs.sh script works, i.e. we see the bug in the console output. -- To view, visit https://gerrit.osmocom.org/954 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I906d7547c055e7943323a472a982d3bbf9c36228 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:04:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:04:03 +0000 Subject: osmo-iuh[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/868 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:04:16 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:04:16 +0000 Subject: libosmocore[master]: jenkins.sh: output all test logs when build failed In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:05:57 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:05:57 +0000 Subject: [ABANDON] openbsc[master]: vty tests: testBSCreload: randomize port for msc In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: vty tests: testBSCreload: randomize port for msc ...................................................................... Abandoned I'm not sure that this is an actual fix -- To view, visit https://gerrit.osmocom.org/945 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I8e1023f6ddd913f95402bb4afb8d02dccda17533 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:28:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:28:15 +0000 Subject: libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 01:28:26 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 01:28:26 +0000 Subject: osmo-iuh[master]: NOT FOR MERGE: testrun for cat-testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/954 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I906d7547c055e7943323a472a982d3bbf9c36228 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:56:31 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:56:31 +0000 Subject: openbsc[master]: cosmetic: vty_test_runner.py: add comment for vim auto settings In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/946 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:56:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:56:47 +0000 Subject: openbsc[master]: vty_test_runner.py: raise exception when MSC socket connecti... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/947 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iae26e7345267a21aed0b108b089453832889c9fa Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:56:52 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:56:52 +0000 Subject: [MERGED] openbsc[master]: vty_test_runner.py: raise exception when MSC socket connecti... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: vty_test_runner.py: raise exception when MSC socket connection fails ...................................................................... vty_test_runner.py: raise exception when MSC socket connection fails Instead of below error, raise an exception to describe what's happening. Seen in a jenkins run on https://gerrit.osmocom.org/#/c/945/2: ERROR: testBSCreload (__main__.TestVTYNAT) ---------------------------------------------------------------------- Traceback (most recent call last): File "./vty_test_runner.py", line 787, in testBSCreload msc = nat_msc_test(self, ip, port) File "./vty_test_runner.py", line 1251, in nat_msc_test return conn UnboundLocalError: local variable 'conn' referenced before assignment Change-Id: Iae26e7345267a21aed0b108b089453832889c9fa --- M openbsc/tests/vty_test_runner.py 1 file changed, 4 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 9fe4c3e..f624fc9 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1233,10 +1233,14 @@ msc.listen(5) if (verbose): print "MSC is ready at " + ip + conn = None while "MSC is connected: 0" == x.vty.command("show msc connection"): conn, addr = msc.accept() if (verbose): print "MSC got connection from ", addr + if not conn: + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): -- To view, visit https://gerrit.osmocom.org/947 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iae26e7345267a21aed0b108b089453832889c9fa Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:56:53 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:56:53 +0000 Subject: [MERGED] openbsc[master]: cosmetic: vty_test_runner.py: add comment for vim auto settings In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: cosmetic: vty_test_runner.py: add comment for vim auto settings ...................................................................... cosmetic: vty_test_runner.py: add comment for vim auto settings Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b --- M openbsc/tests/vty_test_runner.py 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 00eae70..9fe4c3e 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1338,3 +1338,5 @@ add_sgsn_test(suite, workdir) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) + +# vim: set shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/946 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I61a0476a0317b011432bb4f6f593cfdcaf1c072b Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:57:36 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:57:36 +0000 Subject: openbsc[master]: dyn TS: fix: abis_om2000: also handle dyn TS as TCH In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/941 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iddc51a4409488d91db59228ca66aaab73ce3f1df Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:57:44 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:57:44 +0000 Subject: openbsc[master]: channel test: prepare to add another test function In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/936 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1349d0f416806416080d4667ad697f7db1ea252d Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:58:04 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:58:04 +0000 Subject: openbsc[master]: channel_test: test nr of subslots for dyn pchan, with error In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/937 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I09685be3fb3ed1ead4577b772a9fbc31967980d1 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:58:11 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:58:11 +0000 Subject: openbsc[master]: Revert "bts: extend bts_chan_load to allow counting tch only" In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/938 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I34dbbaf53a800115e3d03bd44028cad675f3b525 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:58:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:58:16 +0000 Subject: openbsc[master]: dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/939 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Icd6668667ad2be7ad20866ffd185bf3b8711ccd6 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:59:26 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:59:26 +0000 Subject: openbsc[master]: dyn TS: fix: bs11, om2000: two switch(pchan) for dyn TS In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 dynamic channels don't exist on bs-11 at all. And while Ericsson OM2000 supports dynamic channels, we don't have any PCU support for it (yet) so that it matters very little if we handle it correctly on the BSC side for now. -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:59:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:59:39 +0000 Subject: osmo-sip-connector[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/953 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7db7f7a2e61ba676c2712bcc149a5fd5a69b80b2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:59:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:59:42 +0000 Subject: [MERGED] osmo-sip-connector[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log VTY telnet bind only once ...................................................................... log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: I7db7f7a2e61ba676c2712bcc149a5fd5a69b80b2 --- M src/main.c 1 file changed, 0 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/main.c b/src/main.c index ae4f20a..89706e3 100644 --- a/src/main.c +++ b/src/main.c @@ -135,8 +135,6 @@ exit(1); } - LOGP(DAPP, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_MNCC_SIP); rc = telnet_init_dynif(tall_mncc_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_MNCC_SIP); if (rc < 0) -- To view, visit https://gerrit.osmocom.org/953 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7db7f7a2e61ba676c2712bcc149a5fd5a69b80b2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:59:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:59:46 +0000 Subject: osmo-iuh[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/951 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Icd9e670c1d30c156f7bd5d0d34892150aeba95e9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 04:59:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 04:59:49 +0000 Subject: [MERGED] osmo-iuh[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log VTY telnet bind only once ...................................................................... log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: Icd9e670c1d30c156f7bd5d0d34892150aeba95e9 --- M src/hnbgw.c M src/tests/hnb-test.c 2 files changed, 0 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbgw.c b/src/hnbgw.c index d50e622..8c860b1 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -474,8 +474,6 @@ log_set_log_level(osmo_stderr_target, hnbgw_cmdline_config.log_level); - LOGP(DMAIN, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), 2323); rc = telnet_init_dynif(NULL, g_hnb_gw, vty_get_bind_addr(), 2323); if (rc < 0) { perror("Error binding VTY port"); diff --git a/src/tests/hnb-test.c b/src/tests/hnb-test.c index d338077..68a3117 100644 --- a/src/tests/hnb-test.c +++ b/src/tests/hnb-test.c @@ -944,7 +944,6 @@ vty_init(&vty_info); hnbtest_vty_init(); - printf("VTY at %s %d\n", vty_get_bind_addr(), 2324); rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324); if (rc < 0) { perror("Error binding VTY port"); -- To view, visit https://gerrit.osmocom.org/951 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Icd9e670c1d30c156f7bd5d0d34892150aeba95e9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:00:16 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:00:16 +0000 Subject: openbsc[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/952 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I97a730b28759df1d549a5049f47a3da1c16a3447 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:00:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:00:19 +0000 Subject: [MERGED] openbsc[master]: log VTY telnet bind only once In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log VTY telnet bind only once ...................................................................... log VTY telnet bind only once After libosmocore 55dc2edc89c1a85187ef8aafc09f7d922383231f which outputs 'telnet at ' from telnet_init_dynif(), there's no need to log the telnet VTY bind here anymore. Change-Id: I97a730b28759df1d549a5049f47a3da1c16a3447 --- M openbsc/src/gprs/gb_proxy_main.c M openbsc/src/gprs/gtphub_main.c M openbsc/src/gprs/sgsn_main.c M openbsc/src/libbsc/bsc_init.c M openbsc/src/osmo-bsc_mgcp/mgcp_main.c M openbsc/src/osmo-bsc_nat/bsc_nat.c 6 files changed, 0 insertions(+), 12 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c index 0c3cfbe..2ddfca7 100644 --- a/openbsc/src/gprs/gb_proxy_main.c +++ b/openbsc/src/gprs/gb_proxy_main.c @@ -271,8 +271,6 @@ } /* 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) diff --git a/openbsc/src/gprs/gtphub_main.c b/openbsc/src/gprs/gtphub_main.c index 89582b1..1e20a63 100644 --- a/openbsc/src/gprs/gtphub_main.c +++ b/openbsc/src/gprs/gtphub_main.c @@ -325,8 +325,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DGTPHUB, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_GTPHUB); rc = telnet_init_dynif(osmo_gtphub_ctx, 0, vty_get_bind_addr(), OSMO_VTY_PORT_GTPHUB); if (rc < 0) diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index fb5b6d5..93848f5 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -382,8 +382,6 @@ } /* 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_SGSN); rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, vty_get_bind_addr(), OSMO_VTY_PORT_SGSN); if (rc < 0) diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 06f4121..c38bca1 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -491,8 +491,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_NITB_BSC); rc = telnet_init_dynif(tall_bsc_ctx, bsc_gsmnet, vty_get_bind_addr(), OSMO_VTY_PORT_NITB_BSC); if (rc < 0) diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c index e226b02..ac55e25 100644 --- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c +++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c @@ -233,8 +233,6 @@ return rc; /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DMGCP, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP); rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP); if (rc < 0) diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index f20b248..57cc8b3 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1639,8 +1639,6 @@ } /* start telnet after reading config for vty_get_bind_addr() */ - LOGP(DNAT, LOGL_NOTICE, "VTY at %s %d\n", - vty_get_bind_addr(), OSMO_VTY_PORT_BSC_NAT); if (telnet_init_dynif(tall_bsc_ctx, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_BSC_NAT)) { fprintf(stderr, "Creating VTY telnet line failed\n"); -- To view, visit https://gerrit.osmocom.org/952 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I97a730b28759df1d549a5049f47a3da1c16a3447 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:51:25 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:51:25 +0000 Subject: openbsc[master]: cosmetic: comment typo on e1_config.c In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/935 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I894adf562670abf26665a1eb09592682ab8b31b5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:52:17 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:52:17 +0000 Subject: openbsc[master]: SLHC: Improving slhc (RFC1144) testcase In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/950/1/openbsc/tests/slhc/slhc_test.c File openbsc/tests/slhc/slhc_test.c: Line 177: for (i = 0; i < PACKETS_LEN; i++) { we typically don't mix cosmetic with functional changes, but well, it's a test case, so let's not spend more time on it now. -- To view, visit https://gerrit.osmocom.org/950 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I555fa3c9b9f78424102f359ef1c27b290fa9c9e9 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:52:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:52:20 +0000 Subject: [MERGED] openbsc[master]: SLHC: Improving slhc (RFC1144) testcase In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SLHC: Improving slhc (RFC1144) testcase ...................................................................... SLHC: Improving slhc (RFC1144) testcase - Adding Testcases for UNCOMPRESSED_TCP and TYPE_IP - Minor cosmetic changes Change-Id: I555fa3c9b9f78424102f359ef1c27b290fa9c9e9 --- M openbsc/tests/slhc/slhc_test.c M openbsc/tests/slhc/slhc_test.ok 2 files changed, 130 insertions(+), 56 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c index 59a5425..e8ea02f 100644 --- a/openbsc/tests/slhc/slhc_test.c +++ b/openbsc/tests/slhc/slhc_test.c @@ -38,14 +38,27 @@ #define DISP_MAX_BYTES 100 /* Sample packets to test with */ -#define PACKETS_LEN 6 +#define PACKETS_LEN 15 char *packets[] = { + /* With TCP Option 10 (Timestamps) in place (forces UNCOMPRESSED_TCP) */ "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", - "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20" + "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20", + /* Regular TCP packets (COMPRESSED_TCP) */ + "4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27", + "4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", + "4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01", + "4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01", + "4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", + "4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20", + /* UDP packets (TYPE_IP */ + "450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001", + "450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e6b73c014c00c000200010000173d000603646e73c041c00c000200010000173d000a0767616e65736861c041c058000100010000173d0004d55f2e45c058001c00010000173d0010200107800045f0460000000000690001c06a0001000100006a710004d55f1b78c039000100010000173d000453ecb2cb", + "45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001", + "0050b6162c10000db93a3ff908004500004726a6000038114083080808080a0901650035ef1b00338a8cc3918180000100010000000006676f6f676c650264650000010001c00c000100010000012b0004d83ad503", }; /* Compress a packet using Van Jacobson RFC1144 header compression */ @@ -134,54 +147,13 @@ OSMO_ASSERT(len > 20); OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); + printf("packet[9]=%02x\n", packet[9]); + /* Check TCP packet */ if (packet[9] != 0x06) return; OSMO_ASSERT(len > 40); OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); -} - -/* Strip TCP options from TCP/IP packet */ -static int strip_tcp_options(const void *ctx, uint8_t *packet, int len) -{ - uint8_t doff; - uint16_t csum; - - /* Check if the packet can be handled here */ - if (len < 37) - return len; - if (packet[9] != 0x06) - return len; - - /* Strip TCP/IP options from packet */ - doff = ((packet[32] >> 4) & 0x0F) * 4; - memmove(packet + 40, packet + doff + 20, len - 40 - (doff - 20)); - len = len - (doff - 20); - - /* Repair data offset (TCP header length) */ - packet[32] &= 0x0F; - packet[32] |= 0x50; - - /* Repair checksum */ - packet[36] = 0; - packet[37] = 0; - csum = calc_tcpip_csum(ctx, packet, len); - packet[36] = csum & 0xFF; - packet[37] = csum >> 8 & 0xFF; - - /* Repair total length */ - packet[3] = len & 0xFF; - packet[2] = len >> 8 & 0xFF; - - /* Repair IP header checksum */ - packet[10] = 0; - packet[11] = 0; - csum = calc_ip_csum(packet, 20); - packet[10] = csum & 0xFF; - packet[11] = csum >> 8 & 0xFF; - printf("csum=%04x\n", csum); - - return len; } /* Compress / Decompress packets */ @@ -202,18 +174,18 @@ comp = slhc_init(ctx, SLOTS, SLOTS); OSMO_ASSERT(comp); - for(i=0;i Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:52:41 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:52:41 +0000 Subject: osmo-bts[master]: DTX: remove misleading comment In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/949 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:52:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:52:47 +0000 Subject: [MERGED] osmo-bts[master]: DTX: remove misleading comment In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: DTX: remove misleading comment ...................................................................... DTX: remove misleading comment There's no SID stored in UL direction so there's nothing to remove. Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15 --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 2 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index e06c4cf..bcf981e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -412,7 +412,7 @@ goto err_payload_match; /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP - frame and drop last SID */ + frame */ lchan->rtp_tx_marker = true; break; case GsmL1_TchPlType_Amr_SidFirstP1: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index b1ab086..f350398 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -513,7 +513,7 @@ goto err_payload_match; /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP - frame and drop last SID */ + frame */ lchan->rtp_tx_marker = true; break; case GsmL1_TchPlType_Amr_SidFirstP1: -- To view, visit https://gerrit.osmocom.org/949 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:54:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:54:20 +0000 Subject: libosmo-abis[master]: Unify RTP receiving In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 looks fine to me. Howver, we have very urgent DTX related bugs to fix, so please make sure you focus all your energy to where it really matters. -- To view, visit https://gerrit.osmocom.org/948 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id42e85b55eab33c5eb81ac7a2cdea7962b2e30ef Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:01 +0000 Subject: osmo-iuh[master]: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/944 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:13 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:13 +0000 Subject: osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:23 +0000 Subject: osmo-iuh[master]: hnbap: add UE Register Reject for pTMSIRAI identity In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/942 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:34 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:34 +0000 Subject: osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/910 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:50 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:50 +0000 Subject: osmo-iuh[master]: log: hnbgw: add hnbap UE context allocation info log In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/943 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iac0ca948d6e699d984c6e424afe7106dcaf2ab1e Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:56 +0000 Subject: [MERGED] osmo-iuh[master]: log: hnbgw: add hnbap UE context allocation info log In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log: hnbgw: add hnbap UE context allocation info log ...................................................................... log: hnbgw: add hnbap UE context allocation info log Change-Id: Iac0ca948d6e699d984c6e424afe7106dcaf2ab1e --- M src/hnbgw.c 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbgw.c b/src/hnbgw.c index c326b12..bd0b3ba 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -161,6 +161,9 @@ ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); + LOGP(DHNBAP, LOGL_INFO, "created UE context: id 0x%x, imsi %s, tmsi 0x%x\n", + ue->context_id, imsi? imsi : "-", tmsi); + return ue; } -- To view, visit https://gerrit.osmocom.org/943 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iac0ca948d6e699d984c6e424afe7106dcaf2ab1e Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:56 +0000 Subject: [MERGED] osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: hnbap: accept UE Register Requests with TMSI and pTMSI ...................................................................... hnbap: accept UE Register Requests with TMSI and pTMSI Add the option to allow UE Register Requests with a TMSI identity. Add VTY command to enable this option, 'hnbap-allow-tmsi'. Add hnbgw_tx_ue_register_acc_tmsi(). HNBGW so far keeps track of UEs that have registered, with their IMSI. When a UE registers with only a TMSI, we obviously can't store an IMSI. However, since we're so far never *using* the list of UEs in osmo-hnbgw, we might as well just accept the TMSI registration and carry on as usual. All that is needed for proper operation is a valid UE context. This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. So far this caused failures and the need to make the UE clear its TMSI (wait several minutes or attempt to subscribe to a different network), so that UE registration switched back to IMSI. When simply accepting the TMSI in osmo-hngw, no problems are apparent in our current code state. For example, a Samsung Galaxy S4 seems to send a UE_Identity_PR_tMSILAI (CS identity), and a GT-I9100 seems to send a UE_Identity_PR_pTMSIRAI (PS identity) upon first registration to the network. Recording the IMSI in hnbgw: we could use the subscriber list during paging, to page a UE on only its last seen HNB. On the other hand, it doesn't hurt to anyway always page to all HNBs connected to osmo-hnbgw. The paging procedure does include a page-to-all-HNBs in case the first HNB paging fails. But we must be aware that UEs that register by TMSI will simply not have an IMSI recorded in the list of UE contexts, so a lookup based on IMSI may fail. Patch-by: Harald Welte , me Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw_hnbap.c M src/hnbgw_vty.c 3 files changed, 130 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index bee7fb6..dfe287c 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -117,6 +117,7 @@ * plane traffic from HNBs */ uint16_t iuh_cs_mux_port; uint16_t rnc_id; + bool hnbap_allow_tmsi; } config; /*! SCTP listen socket for incoming connections */ struct osmo_stream_srv_link *iuh; diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 78f4692..59150c9 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -244,6 +244,108 @@ return hnbgw_hnbap_tx(hnb, msg); } +static int hnbgw_tx_ue_register_acc_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id) +{ + UERegisterAccept_t accept_out; + UERegisterAcceptIEs_t accept; + struct msgb *msg; + uint32_t ctx_id; + uint32_t tmsi = 0; + struct ue_context *ue; + int rc; + + memset(&accept, 0, sizeof(accept)); + accept.uE_Identity.present = ue_id->present; + + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.tMSILAI.tMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + break; + + case UE_Identity_PR_pTMSIRAI: + BIT_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.pTMSI, + ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size * 8 + - ue_id->choice.pTMSIRAI.pTMSI.bits_unused); + tmsi = *(uint32_t*)accept.uE_Identity.choice.pTMSIRAI.pTMSI.buf; + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size); + OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.rAC, + ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size); + break; + + default: + LOGP(DHNBAP, LOGL_ERROR, "Unsupportedccept UE ID (present=%d)\n", + ue_id->present); + return -1; + } + + tmsi = ntohl(tmsi); + LOGP(DHNBAP, LOGL_DEBUG, "HNBAP register with TMSI %x\n", + tmsi); + + ue = ue_context_by_tmsi(hnb->gw, tmsi); + if (!ue) + ue = ue_context_alloc(hnb, NULL, tmsi); + + asn1_u24_to_bitstring(&accept.context_ID, &ctx_id, ue->context_id); + + memset(&accept_out, 0, sizeof(accept_out)); + rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept); + if (rc < 0) + return rc; + + msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister, + Criticality_reject, + &asn_DEF_UERegisterAccept, + &accept_out); + + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.tMSILAI.lAI.lAC); + break; + + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &accept.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &accept.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + + default: + /* should never happen after above switch() */ + break; + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterAccept, &accept_out); + + return hnbgw_hnbap_tx(hnb, msg); +} + static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in) { HNBDe_RegisterIEs_t ies; @@ -313,11 +415,19 @@ ranap_bcd_decode(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf, ies.uE_Identity.choice.iMSIESN.iMSIDS41.size); break; + case UE_Identity_PR_tMSILAI: + case UE_Identity_PR_pTMSIRAI: + if (ctx->gw->config.hnbap_allow_tmsi) + rc = hnbgw_tx_ue_register_acc_tmsi(ctx, &ies.uE_Identity); + else + rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); + /* all has been handled by TMSI, skip the IMSI code below */ + hnbap_free_ueregisterrequesties(&ies); + return rc; default: - LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n"); - /* TODO: this is probably a TMSI registration. Store TMSIs - * and look them up to accept UE Registration. */ - rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity); + LOGP(DHNBAP, LOGL_NOTICE, + "UE-REGISTER-REQ with unsupported UE Id type %d\n", + ies.uE_Identity.present); hnbap_free_ueregisterrequesties(&ies); return rc; } diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index 2e3d1e9..d6fad64 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -114,6 +114,16 @@ return CMD_SUCCESS; } +DEFUN(cfg_hnbgw_iuh_hnbap_allow_tmsi, cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd, + "hnbap-allow-tmsi (0|1)", + "Allow HNBAP UE Register messages with TMSI or PTMSI identity\n" + "Only accept IMSI identity, reject TMSI or PTMSI\n" + "Accept IMSI, TMSI or PTMSI as UE identity\n") +{ + g_hnb_gw->config.hnbap_allow_tmsi = (*argv[0] == '1'); + return CMD_SUCCESS; +} + static int config_write_hnbgw(struct vty *vty) { vty_out(vty, "hnbgw%s", VTY_NEWLINE); @@ -130,6 +140,9 @@ if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0)) vty_out(vty, " bind %s%s", addr, VTY_NEWLINE); + if (g_hnb_gw->config.hnbap_allow_tmsi) + vty_out(vty, " hnbap-allow-tmsi 1%s", VTY_NEWLINE); + return CMD_SUCCESS; } @@ -145,7 +158,9 @@ install_element(HNBGW_NODE, &cfg_hnbgw_iuh_cmd); install_node(&iuh_node, config_write_hnbgw_iuh); vty_install_default(IUH_NODE); + install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd); + install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd); install_element_ve(&show_hnb_cmd); install_element_ve(&show_ue_cmd); -- To view, visit https://gerrit.osmocom.org/910 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:56 +0000 Subject: [MERGED] osmo-iuh[master]: hnbap: add UE Register Reject for pTMSIRAI identity In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: hnbap: add UE Register Reject for pTMSIRAI identity ...................................................................... hnbap: add UE Register Reject for pTMSIRAI identity This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. Sending a proper registration reject speeds up the response seen on the UE and avoids needless waiting. See the upcoming commit that enables accepting TMSI identities for further detail. Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c --- M src/hnbgw_hnbap.c 1 file changed, 99 insertions(+), 32 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 7bf54c8..ae0d16c 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -124,54 +124,121 @@ memset(&reject, 0, sizeof(reject)); reject.uE_Identity.present = ue_id->present; - if (ue_id->present != UE_Identity_PR_tMSILAI) { - LOGP(DHNBAP, LOGL_ERROR, "Trying to reject UE Register without IMSI: only rejects of UE_Identity_PR_tMSILAI supported so far.\n"); + /* Copy the identity over to the reject message */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", + ue_id->choice.tMSILAI.tMSI.size, + osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.tMSILAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.tMSILAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size)); + + BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, + ue_id->choice.tMSILAI.tMSI.buf, + ue_id->choice.tMSILAI.tMSI.size * 8 + - ue_id->choice.tMSILAI.tMSI.bits_unused); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, + ue_id->choice.tMSILAI.lAI.pLMNID.buf, + ue_id->choice.tMSILAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, + ue_id->choice.tMSILAI.lAI.lAC.buf, + ue_id->choice.tMSILAI.lAI.lAC.size); + break; + + case UE_Identity_PR_pTMSIRAI: + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pTMSI %d %s\n", + ue_id->choice.pTMSIRAI.pTMSI.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id rAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.rAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size)); + + BIT_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.pTMSI, + ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size * 8 + - ue_id->choice.pTMSIRAI.pTMSI.bits_unused); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size); + OCTET_STRING_fromBuf(&reject.uE_Identity.choice.pTMSIRAI.rAI.rAC, + ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size); + break; + + default: + LOGP(DHNBAP, LOGL_ERROR, "Cannot compose UE Register Reject:" + " unsupported UE ID (present=%d)\n", ue_id->present); return -1; } - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n", - ue_id->choice.tMSILAI.tMSI.size, - osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size)); - - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", - ue_id->choice.tMSILAI.lAI.pLMNID.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size)); - - LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", - ue_id->choice.tMSILAI.lAI.lAC.size, - osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size)); - - BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI, - ue_id->choice.tMSILAI.tMSI.buf, - ue_id->choice.tMSILAI.tMSI.size * 8 - - ue_id->choice.tMSILAI.tMSI.bits_unused); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID, - ue_id->choice.tMSILAI.lAI.pLMNID.buf, - ue_id->choice.tMSILAI.lAI.pLMNID.size); - OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC, - ue_id->choice.tMSILAI.lAI.lAC.buf, - ue_id->choice.tMSILAI.lAI.lAC.size); + LOGP(DHNBAP, LOGL_ERROR, "Rejecting UE Register Request:" + " TMSI identity registration is switched off\n"); reject.cause.present = Cause_PR_radioNetwork; reject.cause.choice.radioNetwork = CauseRadioNetwork_invalid_UE_identity; memset(&reject_out, 0, sizeof(reject_out)); rc = hnbap_encode_ueregisterrejecties(&reject_out, &reject); - if (rc < 0) { + if (rc < 0) return rc; - } msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister, Criticality_reject, &asn_DEF_UERegisterReject, &reject_out); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, &reject.uE_Identity.choice.tMSILAI.tMSI); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.lAC); + /* Free copied identity IEs */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &reject.uE_Identity.choice.tMSILAI.tMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.tMSILAI.lAI.lAC); + break; + + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &reject.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + + default: + /* should never happen after above switch() */ + break; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out); return hnbgw_hnbap_tx(hnb, msg); -- To view, visit https://gerrit.osmocom.org/942 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:56 +0000 Subject: [MERGED] osmo-iuh[master]: hnbgw: UE context: add handling by tmsi identification In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: hnbgw: UE context: add handling by tmsi identification ...................................................................... hnbgw: UE context: add handling by tmsi identification To prepare for an upcoming commit that accepts TMSI identification upon UE Register Requests: Add tmsi arg to ue_context_alloc(). Add ue_context_by_tmsi(). This is aimed at the ip.access nano3G femto cell, as it apparently feeds whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. See the upcoming commit that enables accepting TMSI identities for further detail. Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_hnbap.c 3 files changed, 23 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index 21a9602..bee7fb6 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -101,8 +101,7 @@ /*! Unique Context ID for this UE */ uint32_t context_id; char imsi[16+1]; - /* TODO: track TMSI, for HNBAP UE Register Request with TMSI, - * seen with ip.access nano3G femto cell */ + uint32_t tmsi; /*! UE is serviced via this HNB */ struct hnb_context *hnb; }; @@ -139,7 +138,9 @@ struct ue_context *ue_context_by_id(struct hnb_gw *gw, uint32_t id); struct ue_context *ue_context_by_imsi(struct hnb_gw *gw, const char *imsi); -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi); +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi); +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi); void ue_context_free(struct ue_context *ue); struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd); diff --git a/src/hnbgw.c b/src/hnbgw.c index 8c860b1..c326b12 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -111,6 +111,17 @@ return NULL; } +struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi) +{ + struct ue_context *ue; + + llist_for_each_entry(ue, &gw->ue_list, list) { + if (ue->tmsi == tmsi) + return ue; + } + return NULL; +} + void ue_context_free_by_hnb(struct hnb_gw *gw, const struct hnb_context *hnb) { struct ue_context *ue, *tmp; @@ -132,7 +143,8 @@ return id; } -struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi) +struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi, + uint32_t tmsi) { struct ue_context *ue; @@ -141,7 +153,11 @@ return NULL; ue->hnb = hnb; - strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + if (imsi) + strncpy(ue->imsi, imsi, sizeof(ue->imsi)); + else + ue->imsi[0] = '\0'; + ue->tmsi = tmsi; ue->context_id = get_next_ue_ctx_id(hnb->gw); llist_add_tail(&ue->list, &hnb->gw->ue_list); diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index ae0d16c..78f4692 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -327,7 +327,7 @@ ue = ue_context_by_imsi(ctx->gw, imsi); if (!ue) - ue = ue_context_alloc(ctx, imsi); + ue = ue_context_alloc(ctx, imsi, 0); hnbap_free_ueregisterrequesties(&ies); /* Send UERegisterAccept */ -- To view, visit https://gerrit.osmocom.org/909 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I138458443319cc4cbea5ee7906cf5dd72d582130 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 05:55:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 27 Sep 2016 05:55:56 +0000 Subject: [MERGED] osmo-iuh[master]: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' ...................................................................... hnbgw: vty conformance: rename iuh 'bind' command to 'local-ip' The standard osmo VTY terminology is 'remote-ip', 'remote-port', 'local-ip', 'local-port'. Conform to that. osmo-hnbgw is so far not rolled out widely, so it makes sense to do this now. Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 --- M include/osmocom/iuh/hnbgw.h M src/hnbgw.c M src/hnbgw_vty.c 3 files changed, 7 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h index dfe287c..dfc9d82 100644 --- a/include/osmocom/iuh/hnbgw.h +++ b/include/osmocom/iuh/hnbgw.h @@ -106,7 +106,7 @@ struct hnb_context *hnb; }; -#define HNBGW_IUH_BIND_ADDR_DEFAULT "0.0.0.0" +#define HNBGW_IUH_LOCAL_IP_DEFAULT "0.0.0.0" struct hnb_gw { struct { diff --git a/src/hnbgw.c b/src/hnbgw.c index bd0b3ba..500cf0f 100644 --- a/src/hnbgw.c +++ b/src/hnbgw.c @@ -312,7 +312,7 @@ { const char *addr = gw->config.iuh_bind_addr; if (!addr) - addr = HNBGW_IUH_BIND_ADDR_DEFAULT; + addr = HNBGW_IUH_LOCAL_IP_DEFAULT; return addr; } diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c index d6fad64..5dee41a 100644 --- a/src/hnbgw_vty.c +++ b/src/hnbgw_vty.c @@ -105,9 +105,9 @@ return CMD_SUCCESS; } -DEFUN(cfg_hnbgw_iuh_bind, cfg_hnbgw_iuh_bind_cmd, "bind A.B.C.D", +DEFUN(cfg_hnbgw_iuh_local_ip, cfg_hnbgw_iuh_local_ip_cmd, "local-ip A.B.C.D", "Accept Iuh connections on local interface\n" - "Local interface IP address (default: " HNBGW_IUH_BIND_ADDR_DEFAULT ")") + "Local interface IP address (default: " HNBGW_IUH_LOCAL_IP_DEFAULT ")") { talloc_free((void*)g_hnb_gw->config.iuh_bind_addr); g_hnb_gw->config.iuh_bind_addr = talloc_strdup(tall_hnb_ctx, argv[0]); @@ -137,8 +137,8 @@ vty_out(vty, " iuh%s", VTY_NEWLINE); addr = g_hnb_gw->config.iuh_bind_addr; - if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0)) - vty_out(vty, " bind %s%s", addr, VTY_NEWLINE); + if (addr && (strcmp(addr, HNBGW_IUH_LOCAL_IP_DEFAULT) != 0)) + vty_out(vty, " local-ip %s%s", addr, VTY_NEWLINE); if (g_hnb_gw->config.hnbap_allow_tmsi) vty_out(vty, " hnbap-allow-tmsi 1%s", VTY_NEWLINE); @@ -159,7 +159,7 @@ install_node(&iuh_node, config_write_hnbgw_iuh); vty_install_default(IUH_NODE); - install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd); + install_element(IUH_NODE, &cfg_hnbgw_iuh_local_ip_cmd); install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd); install_element_ve(&show_hnb_cmd); -- To view, visit https://gerrit.osmocom.org/944 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifda2653bf58044552a5f1477cd7008dec3fb9100 Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 06:33:05 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 27 Sep 2016 06:33:05 +0000 Subject: osmo-bts[master]: measurement.c In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/901/1//COMMIT_MSG Commit Message: Line 7: measurement.c This line usually holds a "subject/summary". It is nice to know which file/subsystem was changed but please indicate what this change is about. -- To view, visit https://gerrit.osmocom.org/901 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Sep 27 08:38:30 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 08:38:30 +0000 Subject: libosmo-abis[master]: Unify RTP receiving In-Reply-To: References: Message-ID: Patch Set 1: Sure, that's just by-product of debug messages which I've added for DTX locally and which are too verbose to push for master. For adding those it was easier to consolidate the code and as it's independent of the debug messages I've decided to push that patch right away. -- To view, visit https://gerrit.osmocom.org/948 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id42e85b55eab33c5eb81ac7a2cdea7962b2e30ef Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:39:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:39:31 +0000 Subject: openbsc[master]: dyn TS: fix: bs11, om2000: two switch(pchan) for dyn TS In-Reply-To: References: Message-ID: Patch Set 2: > dynamic channels don't exist on bs-11 at all. heh, ok, wasn't aware of it. > And while Ericsson OM2000 supports dynamic channels, > we don't have any PCU support for it (yet) ok, I see. I still think it is generally good to heed the logic of the TCH/F_PDCH and TCH/F_TCH/H_PDCH pchan types. -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:47:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:47:01 +0000 Subject: [PATCH] libosmocore[master]: gsm0408_test: initialize msgb talloc ctx Message-ID: Review at https://gerrit.osmocom.org/955 gsm0408_test: initialize msgb talloc ctx Change-Id: Ib26214add1932e93651c248cc09fbc68339b4dce --- M tests/gsm0408/gsm0408_test.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/55/955/1 diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index b469b30..f922a4f 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -149,6 +149,7 @@ int main(int argc, char **argv) { + msgb_talloc_ctx_init(NULL, 0); test_bearer_cap(); test_mid_from_tmsi(); -- To view, visit https://gerrit.osmocom.org/955 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib26214add1932e93651c248cc09fbc68339b4dce Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:55:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:55:33 +0000 Subject: [PATCH] openbsc[master]: dyn TS: fix: e1_config.c: switch(pchan) for dyn TS In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/940 to look at the new patch set (#3). dyn TS: fix: e1_config.c: switch(pchan) for dyn TS Add ts_is_tch() in gsm_data_shared.h/.c and use it to replace a switch on the pchan in e1_config.c. This patch is not due to an actual observed failure. A general grep for switch on pchan turned up this instance that doesn't handle dyn TS properly. Hence this patch is not actually tested with real equipment. Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/e1_config.c M openbsc/src/libcommon/gsm_data_shared.c 3 files changed, 18 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/40/940/3 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 7c8fb59..368ac6b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -855,5 +855,6 @@ int *rc); uint8_t ts_subslots(struct gsm_bts_trx_ts *ts); +bool ts_is_tch(struct gsm_bts_trx_ts *ts); #endif diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index d82b009..0c3250f 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -63,15 +63,10 @@ return -ENOMEM; } - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) { e1_ts = &line->ts[e1_link->e1_ts-1]; e1inp_ts_config_trau(e1_ts, line, subch_cb); subch_demux_activate(&e1_ts->trau.demux, e1_link->e1_ts_ss); - break; - default: - break; } return 0; diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 371e479..4eea21e 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -747,3 +747,19 @@ { return subslots_per_pchan[ts_pchan(ts)]; } + +static bool pchan_is_tch(enum gsm_phys_chan_config pchan) +{ + switch (pchan) { + case GSM_PCHAN_TCH_F: + case GSM_PCHAN_TCH_H: + return true; + default: + return false; + } +} + +bool ts_is_tch(struct gsm_bts_trx_ts *ts) +{ + return pchan_is_tch(ts_pchan(ts)); +} -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:55:33 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:55:33 +0000 Subject: [PATCH] openbsc[master]: cosmetic: bs11: also use ts_is_tch() Message-ID: Review at https://gerrit.osmocom.org/956 cosmetic: bs11: also use ts_is_tch() Use the recently added ts_is_tch() function instead of an explicit switch to determine TCH pchan types. This is a cosmetic change since the bs11 does not support dynamic channels (which was the main motivator behind ts_is_tch()). Change-Id: Idf8ce51c76a83210fe3d70e18c51bbaffebb8ad5 --- M openbsc/src/libbsc/bts_siemens_bs11.c 1 file changed, 1 insertion(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/56/956/1 diff --git a/openbsc/src/libbsc/bts_siemens_bs11.c b/openbsc/src/libbsc/bts_siemens_bs11.c index 160563b..c083b1e 100644 --- a/openbsc/src/libbsc/bts_siemens_bs11.c +++ b/openbsc/src/libbsc/bts_siemens_bs11.c @@ -400,15 +400,9 @@ if (is_ipaccess_bts(ts->trx->bts)) return; - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts, e1l->e1_ts_ss); - break; - default: - break; - } } static void nm_reconfig_trx(struct gsm_bts_trx *trx) -- To view, visit https://gerrit.osmocom.org/956 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idf8ce51c76a83210fe3d70e18c51bbaffebb8ad5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:56:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:56:58 +0000 Subject: libosmocore[master]: gsm0408_test: initialize msgb talloc ctx In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/955 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib26214add1932e93651c248cc09fbc68339b4dce Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:57:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:57:00 +0000 Subject: [MERGED] libosmocore[master]: gsm0408_test: initialize msgb talloc ctx In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: gsm0408_test: initialize msgb talloc ctx ...................................................................... gsm0408_test: initialize msgb talloc ctx Change-Id: Ib26214add1932e93651c248cc09fbc68339b4dce --- M tests/gsm0408/gsm0408_test.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index b469b30..f922a4f 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -149,6 +149,7 @@ int main(int argc, char **argv) { + msgb_talloc_ctx_init(NULL, 0); test_bearer_cap(); test_mid_from_tmsi(); -- To view, visit https://gerrit.osmocom.org/955 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib26214add1932e93651c248cc09fbc68339b4dce Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:57:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:57:00 +0000 Subject: [MERGED] libosmocore[master]: msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_ctx() ...................................................................... msgb: add msgb_talloc_ctx_init(), deprecate msgb_set_talloc_ctx() So far each and every main() scope creates a msgb talloc context and either passes it to msgb_set_talloc_ctx() or sets tall_msgb_ctx directly (by defining it extern first). Remove some code duplication: add one central function that creates the "msgb" talloc context for all. Most users of msgb employ a talloc_named_const(), but osmo-bts uses a talloc_pool() instead. Offer both ways by means of the pool_size argument, and for both ways make sure the context is called "msgb". Suggest that msgb users should move to this new function: deprecate msgb_set_talloc_ctx(). To be able to do so, include core/defs.h in msgb.h. There's a tradeoff between hiding the msgb talloc context behind API that tries to guess all use cases versus avoiding code dup. This patch opts against code dup and boldly assumes that all future use is covered. Also, the new function suggests to not access tall_msgb_ctx directly, which can be considered a style improvement. It seems that not all main scopes that use msgb actually initialize the msgb ctx. As a fallback for these, explicitly initialize tall_msgb_ctx to NULL. Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c --- M include/osmocom/core/msgb.h M src/msgb.c 2 files changed, 24 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 6f617e2..7c85771 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -23,6 +23,7 @@ #include #include #include +#include /*! \defgroup msgb Message buffers * @{ @@ -457,6 +458,8 @@ /* non inline functions to ease binding */ uint8_t *msgb_data(const struct msgb *msg); -void msgb_set_talloc_ctx(void *ctx); + +void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size); +void msgb_set_talloc_ctx(void *ctx) OSMO_DEPRECATED("Use msgb_talloc_ctx_init() instead"); /*! @} */ diff --git a/src/msgb.c b/src/msgb.c index ea8dc82..a27100c 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -35,7 +35,7 @@ #include //#include -void *tall_msgb_ctx; +void *tall_msgb_ctx = NULL; /*! \brief Allocate a new message buffer * \param[in] size Length in octets, including headroom @@ -151,6 +151,7 @@ } /*! \brief Set the talloc context for \ref msgb_alloc + * Deprecated, use msgb_talloc_ctx_init() instead. * \param[in] ctx talloc context to be used as root for msgb allocations */ void msgb_set_talloc_ctx(void *ctx) @@ -158,6 +159,24 @@ tall_msgb_ctx = ctx; } +/*! \brief Initialize a msgb talloc context for \ref msgb_alloc. + * Create a talloc context called "msgb". If \a pool_size is 0, create a named + * const as msgb talloc context. If \a pool_size is nonzero, create a talloc + * pool, possibly for faster msgb allocations (see talloc_pool()). + * \param[in] root_ctx talloc context used as parent for the new "msgb" ctx. + * \param[in] pool_size if nonzero, create a talloc pool of this size. + * \returns the new msgb talloc context, e.g. for reporting + */ +void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size) +{ + if (!pool_size) + tall_msgb_ctx = talloc_size(root_ctx, 0); + else + tall_msgb_ctx = talloc_pool(root_ctx, pool_size); + talloc_set_name_const(tall_msgb_ctx, "msgb"); + return tall_msgb_ctx; +} + /*! \brief Copy an msgb. * * This function allocates a new msgb, copies the data buffer of msg, -- To view, visit https://gerrit.osmocom.org/847 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I747fbbf977c4d2c868c8dead64cfc5fd86eb8d4c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 09:59:39 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 27 Sep 2016 09:59:39 +0000 Subject: [MERGED] openbsc[master]: cosmetic: comment typo on e1_config.c In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: cosmetic: comment typo on e1_config.c ...................................................................... cosmetic: comment typo on e1_config.c Change-Id: I894adf562670abf26665a1eb09592682ab8b31b5 --- M openbsc/src/libbsc/e1_config.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index d82b009..803772b 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -37,7 +37,7 @@ #define SAPI_OML 62 #define SAPI_RSL 0 /* 63 ? */ -/* The e1_reconfig_*() functions below tale the configuration present in the +/* The e1_reconfig_*() functions below take the configuration present in the * bts/trx/ts data structures and ensure the E1 configuration reflects the * timeslot/subslot/TEI configuration */ -- To view, visit https://gerrit.osmocom.org/935 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I894adf562670abf26665a1eb09592682ab8b31b5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Sep 27 10:36:11 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 10:36:11 +0000 Subject: [PATCH] osmo-bts[master]: DTX: invalidate cached SID on speech resume Message-ID: Review at https://gerrit.osmocom.org/957 DTX: invalidate cached SID on speech resume Ideally AMR have special ONSET event for speech resume which is propagated into RTP header Marker bit. However this packet could be lost so we should infer this event also by the presence os speech frames and correspondingly drop saved SID. Change-Id: I6ab91f6ce5402b1614be2ab458da65ecd8624fdc --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/57/957/1 diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index e06c4cf..57aafa6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -221,6 +221,8 @@ case 4: case 5: case 6: case 7: cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; break; case AMR_NO_DATA: LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index b1ab086..5de8caa 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -318,6 +318,8 @@ case 4: case 5: case 6: case 7: cmi = ft; LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; break; case AMR_NO_DATA: LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); -- To view, visit https://gerrit.osmocom.org/957 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6ab91f6ce5402b1614be2ab458da65ecd8624fdc Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Sep 27 10:36:11 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 10:36:11 +0000 Subject: [PATCH] osmo-bts[master]: DTX: remove excessive logging Message-ID: Review at https://gerrit.osmocom.org/958 DTX: remove excessive logging Decrease log verbosity - this will allow to avoid extra decoding of RTP packet just for logging. Change-Id: Ic797131b088fce80e553e0a7bb85ba744590b252 --- M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 2 files changed, 4 insertions(+), 16 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/58/958/1 diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 57aafa6..b8c278d 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -302,10 +302,7 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; + uint8_t *l1_payload; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -335,10 +332,7 @@ if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", - get_value_string(osmo_amr_type_names, ft)); + LOGP(DRTP, LOGL_DEBUG, "AMR SPEECH frame with Marker\n"); } else { *payload_type = GsmL1_TchPlType_Amr; diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 5de8caa..0abb811 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -399,10 +399,7 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; + uint8_t *l1_payload; int rc; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -434,10 +431,7 @@ if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", - get_value_string(osmo_amr_type_names, ft)); + LOGP(DRTP, LOGL_DEBUG, "AMR SPEECH frame with Marker\n"); } else { *payload_type = GsmL1_TchPlType_Amr; -- To view, visit https://gerrit.osmocom.org/958 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic797131b088fce80e553e0a7bb85ba744590b252 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Sep 27 11:42:27 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 11:42:27 +0000 Subject: [ABANDON] osmo-bts[master]: DTX: remove excessive logging In-Reply-To: References: Message-ID: Max has abandoned this change. Change subject: DTX: remove excessive logging ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/958 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ic797131b088fce80e553e0a7bb85ba744590b252 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 11:54:13 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 11:54:13 +0000 Subject: [PATCH] libosmocore[master]: AMR: add function to check speech frames Message-ID: Review at https://gerrit.osmocom.org/959 AMR: add function to check speech frames Add convenience function osmo_amr_is_speech() to check if given AMR frame is speech frame: non-speech frames often require special processing. Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 --- M include/osmocom/codec/codec.h M src/codec/gsm690.c 2 files changed, 22 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/59/959/1 diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index f7a8ad9..305fad9 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -44,6 +44,7 @@ bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len); bool osmo_hr_check_sid(uint8_t *rtp_payload, size_t payload_len); +bool osmo_amr_is_speech(enum osmo_amr_type ft); int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft, enum osmo_amr_quality bfi); int osmo_amr_rtp_dec(const uint8_t *payload, int payload_len, uint8_t *cmr, diff --git a/src/codec/gsm690.c b/src/codec/gsm690.c index 0f4bf8f..fc1ca3d 100644 --- a/src/codec/gsm690.c +++ b/src/codec/gsm690.c @@ -235,6 +235,27 @@ { 0, NULL }, }; +/*! \brief Check if given AMR Frame Type is a speech frame + * \param[in] ft AMR Frame Type + * \returns true if AMR with given Frame Type contains voice, false otherwise + */ +bool osmo_amr_is_speech(enum osmo_amr_type ft) +{ + switch (ft) { + case AMR_4_75: + case AMR_5_15: + case AMR_5_90: + case AMR_6_70: + case AMR_7_40: + case AMR_7_95: + case AMR_10_2: + case AMR_12_2: + return true; + default: + return false; + } +} + /*! \brief Decode various AMR parameters from RTP payload (RFC 4867) acording to * 3GPP TS 26.101 * \param[in] rtppayload Payload from RTP packet -- To view, visit https://gerrit.osmocom.org/959 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Sep 27 17:27:37 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 17:27:37 +0000 Subject: [ABANDON] osmo-bts[master]: DTX: invalidate cached SID on speech resume In-Reply-To: References: Message-ID: Max has abandoned this change. Change subject: DTX: invalidate cached SID on speech resume ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/957 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I6ab91f6ce5402b1614be2ab458da65ecd8624fdc Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Sep 27 18:00:31 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 18:00:31 +0000 Subject: [PATCH] osmo-bts[master]: DTX: further SID caching fixes (lc15, sysmo) Message-ID: Review at https://gerrit.osmocom.org/960 DTX: further SID caching fixes (lc15, sysmo) * consolidate AMR CMR and CMI handling in common/amr.c * use it in save_last_sid() * remove dead code * properly compute RTP payload length for AMR * use save_last_sid() for FR & HR as well * invalidate cached SID if SPEECH frame is received Fixes: OS #1800, #1801 Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed --- M include/osmo-bts/amr.h M include/osmo-bts/msg_utils.h M src/common/amr.c M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 6 files changed, 123 insertions(+), 171 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/60/960/1 diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index 6bdc41f..f313287 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -11,7 +11,8 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, const uint8_t *mr_conf, unsigned int len); -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi); +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f03eb43..8ba1866 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -25,7 +25,7 @@ void lchan_set_marker(bool t, struct gsm_lchan *lchan); void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); + uint32_t fn, int update, uint8_t cmr, int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/common/amr.c b/src/common/amr.c index 56ed430..9d8a428 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -22,7 +22,8 @@ LOGPC(ss, logl, "\n"); } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) +static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) { unsigned int i; for (i = 0; i < amr_mrc->num_modes; i++) { @@ -32,6 +33,44 @@ return -EINVAL; } +static inline uint8_t set_cmr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmr) +{ + /* Codec Mode Request is in upper 4 bits of RTP payload header, + * and we simply copy the CMR into the CMC */ + if (cmr == 0xF) { + /* FIXME: we need some state about the last codec mode */ + return 0; + } + + rc = get_amr_mode_idx(amr_mrc, cmr); + if (rc < 0) { + /* FIXME: we need some state about the last codec mode */ + LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); + return 0; + } + return rc; +} + +static inline uint8_t set_cmi_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) +{ + int rc = get_amr_mode_idx(amr_mrc, cmi); + if (rc < 0) { + LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", + cmi); + return 0; + } + return rc; +} + +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr) +{ + data[0] = set_cmi_mode_idx(amr_mrc, cmi); + data[1] = set_cmr_mode_idx(amr_mrc, cmr); +} + /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more * comfortable internal data structure */ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 967b10d..bcbed5b 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -99,17 +100,29 @@ } /* store the last SID frame in lchan context */ +/*! \brief Store the last SID frame in lchan context + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] l1_payload buffer with SID data + * \param[in] length length of l1_payload + * \param[in] fn Frame Number for which we check scheduling + * \param[in] update 0 if SID_FIRST, 1 if SID_UPDATE, -1 if not AMR SID + * \param[in] cmr Codec Mode Request (AMR-specific, ignored otherwise) + * \param[in] cmi Codec Mode Indication (AMR-specific, ignored otherwise) + */ void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) + uint32_t fn, int update, uint8_t cmr, int8_t cmi) { - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); + size_t amr = (update < 0) ? 0 : 2, + copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; + lchan->tch.last_sid.len = copy_len + amr; lchan->tch.last_sid.fn = fn; lchan->tch.last_sid.is_update = update; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); + if (amr) + amr_set_mode_pref(lchan->tch.last_sid.buf, &lchan->tch.amr_mr, + cmi, cmr); + memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } /* repeat last SID if possible, returns SID length + 1 or 0 */ diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index bcf981e..2fd935e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,85 +200,12 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); memcpy(l1_payload+2, rtp_payload, payload_len); + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -305,6 +232,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -318,32 +246,54 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index f350398..714570c 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,19 +283,8 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - #ifdef USE_L1_RTP_MODE memcpy(l1_payload+2, rtp_payload, payload_len); #else @@ -310,72 +299,9 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -402,6 +328,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -415,34 +342,56 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; #endif case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Sep 27 18:00:32 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 27 Sep 2016 18:00:32 +0000 Subject: [PATCH] osmo-bts[master]: DTX: force ONSET on talkspurt Message-ID: Review at https://gerrit.osmocom.org/961 DTX: force ONSET on talkspurt Ideally AMR have special ONSET event for speech resume which is propagated into RTP header Marker bit. However this packet could be lost so we should infer this event also by the presence os speech frames and correspondingly drop saved SID. Fixes: OS#1802 Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 54 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/1 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..f78276a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -443,6 +443,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -466,14 +467,18 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { msgb_free(nmsg); nmsg = NULL; } + + if (rc > 0) /* force ONSET event */ + l1sap->u.tch.marker = 1; } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 2fd935e..fb3dca7 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -214,7 +214,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -223,7 +225,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -231,7 +233,7 @@ enum osmo_amr_type ft; enum osmo_amr_quality bfi; int8_t sti, cmi; - int rc; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -270,24 +272,31 @@ if (ft == AMR_SID) { save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); - return false; + return -EAGAIN; } if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return false; + return -ENOTSUP; } if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + if (lchan->tch.last_sid.len) { /* force ONSET */ marker = true; + rc = 1; } /* We received AMR SPEECH frame - invalidate saved SID */ lchan->tch.last_sid.len = 0; } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return rc; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { @@ -305,14 +314,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..06711e4 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,14 +460,18 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { msgb_free(nmsg); nmsg = NULL; } + + if (rc > 0) /* force ONSET event */ + l1sap->u.tch.marker = 1; } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 714570c..879ed33 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -310,7 +310,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -319,7 +321,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -327,7 +329,7 @@ enum osmo_amr_type ft; enum osmo_amr_quality bfi; int8_t sti, cmi; - int rc; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -368,24 +370,31 @@ if (ft == AMR_SID) { save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); - return false; + return -EAGAIN; } if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return false; + return -ENOTSUP; } if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + if (lchan->tch.last_sid.len) { /* force ONSET */ marker = true; + rc = 1; } /* We received AMR SPEECH frame - invalidate saved SID */ lchan->tch.last_sid.len = 0; } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return rc; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { @@ -403,14 +412,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:22:23 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:22:23 +0000 Subject: [PATCH] openbsc[master]: COSMETIC: 'if' is not a function, so there is space before '(' Message-ID: Review at https://gerrit.osmocom.org/962 COSMETIC: 'if' is not a function, so there is space before '(' Change-Id: Ic22623dffce998d70a3c67aa6e445de98f558ed7 --- M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/libmgcp/mgcp_protocol.c M openbsc/src/osmo-bsc/osmo_bsc_sccp.c 5 files changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/62/962/1 diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index ff771b8..5b1f333 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -1066,7 +1066,7 @@ /* Generate XID message */ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),llme->iov_ui,llme); - if(xid_bytes_len < 0) + if (xid_bytes_len < 0) return -EINVAL; xid = msgb_put(msg, xid_bytes_len); memcpy(xid, xid_bytes, xid_bytes_len); @@ -1099,7 +1099,7 @@ /* Generate XID message */ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),llme->iov_ui,llme); - if(xid_bytes_len < 0) + if (xid_bytes_len < 0) return -EINVAL; xid = msgb_put(msg, xid_bytes_len); memcpy(xid, xid_bytes, xid_bytes_len); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 0b18f81..1cbeede 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -779,7 +779,7 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); - if(scomph) { + if (scomph) { sne->defrag.pcomp = scomph->pcomp; sne->defrag.dcomp = scomph->dcomp; sne->defrag.proto = lle->llme->comp.proto; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 9f65325..127ee30 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -328,13 +328,13 @@ /* Send PDP CTX ACT to MS */ rc = gsm48_tx_gsm_act_pdp_acc(pctx); - if(rc < 0) + if (rc < 0) return rc; /* Send SNDCP XID to MS */ lle = &pctx->mm->gb.llme->lle[pctx->sapi]; rc = sndcp_sn_xid_req(lle,pctx->nsapi); - if(rc < 0) + if (rc < 0) return rc; return 0; diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index ff0fc3e..2e728cb 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -818,7 +818,7 @@ if (osmux_cid >= 0) { endp->osmux.cid = osmux_cid; endp->osmux.state = OSMUX_STATE_NEGOTIATING; - } else if(endp->cfg->osmux == OSMUX_USAGE_ONLY) { + } else if (endp->cfg->osmux == OSMUX_USAGE_ONLY) { LOGP(DMGCP, LOGL_ERROR, "Osmux only and no osmux offered on 0x%x\n", ENDPOINT_NUMBER(endp)); goto error2; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c index 33c737f..86b27be 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c @@ -80,7 +80,7 @@ if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) { con_data = (struct osmo_bsc_sccp_con *) conn->data_ctx; - if(con_data->conn) { + if (con_data->conn) { LOGP(DMSC, LOGL_ERROR, "ERROR: The lchan is still associated.\n"); gsm0808_clear(con_data->conn); -- To view, visit https://gerrit.osmocom.org/962 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic22623dffce998d70a3c67aa6e445de98f558ed7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:24:33 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:24:33 +0000 Subject: openbsc[master]: COSMETIC: 'if' is not a function, so there is space before '(' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/962 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic22623dffce998d70a3c67aa6e445de98f558ed7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:26:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:26:49 +0000 Subject: osmo-bts[master]: DTX: further SID caching fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:27:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:27:00 +0000 Subject: osmo-bts[master]: DTX: force ONSET on talkspurt In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:27:49 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:27:49 +0000 Subject: openbsc[master]: dyn TS: fix: e1_config.c: switch(pchan) for dyn TS In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:27:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:27:58 +0000 Subject: openbsc[master]: cosmetic: bs11: also use ts_is_tch() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/956 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idf8ce51c76a83210fe3d70e18c51bbaffebb8ad5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:02 +0000 Subject: [MERGED] openbsc[master]: cosmetic: bs11: also use ts_is_tch() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: cosmetic: bs11: also use ts_is_tch() ...................................................................... cosmetic: bs11: also use ts_is_tch() Use the recently added ts_is_tch() function instead of an explicit switch to determine TCH pchan types. This is a cosmetic change since the bs11 does not support dynamic channels (which was the main motivator behind ts_is_tch()). Change-Id: Idf8ce51c76a83210fe3d70e18c51bbaffebb8ad5 --- M openbsc/src/libbsc/bts_siemens_bs11.c 1 file changed, 1 insertion(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/bts_siemens_bs11.c b/openbsc/src/libbsc/bts_siemens_bs11.c index 160563b..c083b1e 100644 --- a/openbsc/src/libbsc/bts_siemens_bs11.c +++ b/openbsc/src/libbsc/bts_siemens_bs11.c @@ -400,15 +400,9 @@ if (is_ipaccess_bts(ts->trx->bts)) return; - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts, e1l->e1_ts_ss); - break; - default: - break; - } } static void nm_reconfig_trx(struct gsm_bts_trx *trx) -- To view, visit https://gerrit.osmocom.org/956 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idf8ce51c76a83210fe3d70e18c51bbaffebb8ad5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:02 +0000 Subject: [MERGED] openbsc[master]: dyn TS: fix: e1_config.c: switch(pchan) for dyn TS In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: dyn TS: fix: e1_config.c: switch(pchan) for dyn TS ...................................................................... dyn TS: fix: e1_config.c: switch(pchan) for dyn TS Add ts_is_tch() in gsm_data_shared.h/.c and use it to replace a switch on the pchan in e1_config.c. This patch is not due to an actual observed failure. A general grep for switch on pchan turned up this instance that doesn't handle dyn TS properly. Hence this patch is not actually tested with real equipment. Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/e1_config.c M openbsc/src/libcommon/gsm_data_shared.c 3 files changed, 18 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 7c8fb59..368ac6b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -855,5 +855,6 @@ int *rc); uint8_t ts_subslots(struct gsm_bts_trx_ts *ts); +bool ts_is_tch(struct gsm_bts_trx_ts *ts); #endif diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 803772b..f1962c7 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -63,15 +63,10 @@ return -ENOMEM; } - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: + if (ts_is_tch(ts)) { e1_ts = &line->ts[e1_link->e1_ts-1]; e1inp_ts_config_trau(e1_ts, line, subch_cb); subch_demux_activate(&e1_ts->trau.demux, e1_link->e1_ts_ss); - break; - default: - break; } return 0; diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 371e479..4eea21e 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -747,3 +747,19 @@ { return subslots_per_pchan[ts_pchan(ts)]; } + +static bool pchan_is_tch(enum gsm_phys_chan_config pchan) +{ + switch (pchan) { + case GSM_PCHAN_TCH_F: + case GSM_PCHAN_TCH_H: + return true; + default: + return false; + } +} + +bool ts_is_tch(struct gsm_bts_trx_ts *ts) +{ + return pchan_is_tch(ts_pchan(ts)); +} -- To view, visit https://gerrit.osmocom.org/940 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ide4f156034bab77140d2d9a8c462d68ae6f0d6a6 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:02 +0000 Subject: [MERGED] openbsc[master]: dyn TS: fix: abis_om2000: also handle dyn TS as TCH In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: dyn TS: fix: abis_om2000: also handle dyn TS as TCH ...................................................................... dyn TS: fix: abis_om2000: also handle dyn TS as TCH Add ts2comb() to switch on dyn TS so that dyn TS in TCH mode are also treated like normal TCH/H or TCH/F pchans. Use ts2comb() instead of pchan2comb(). Change-Id: Iddc51a4409488d91db59228ca66aaab73ce3f1df --- M openbsc/src/libbsc/abis_om2000.c 1 file changed, 16 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c index 2e5a79a..1745a72 100644 --- a/openbsc/src/libbsc/abis_om2000.c +++ b/openbsc/src/libbsc/abis_om2000.c @@ -1123,10 +1123,24 @@ case GSM_PCHAN_TCH_F: case GSM_PCHAN_TCH_H: case GSM_PCHAN_PDCH: - case GSM_PCHAN_TCH_F_PDCH: return 8; default: return 0; + } +} + +static uint8_t ts2comb(struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F_PDCH: + if (ts->flags & TS_F_PDCH_ACTIVE) + return pchan2comb(GSM_PCHAN_PDCH); + else + return pchan2comb(GSM_PCHAN_TCH_F); + case GSM_PCHAN_TCH_F_TCH_H_PDCH: + return pchan2comb(ts->dyn.pchan_is); + default: + return pchan2comb(ts->pchan); } } @@ -1179,7 +1193,7 @@ o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TS_CONF_REQ); - msgb_tv_put(msg, OM2K_DEI_COMBINATION, pchan2comb(ts->pchan)); + msgb_tv_put(msg, OM2K_DEI_COMBINATION, ts2comb(ts)); msgb_tv_put(msg, OM2K_DEI_TS_NR, ts->nr); msgb_tlv_put(msg, OM2K_DEI_FREQ_LIST, freq_list_len, freq_list); msgb_tv_put(msg, OM2K_DEI_HSN, ts->hopping.hsn); -- To view, visit https://gerrit.osmocom.org/941 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iddc51a4409488d91db59228ca66aaab73ce3f1df Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:02 +0000 Subject: [MERGED] openbsc[master]: dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode ...................................................................... dyn TS: fix: ts_subslots() for TCH/F_PDCH in PDCH mode In gsm_data_shared.c, add ts_pchan() to determine actual pchan type for dynamic and non-dynamic TS. Use in ts_subslots() to fix the value returned for TCH/F_PDCH in PDCH mode. Adjust the assertion in channel_test.c accordingly. Drop GSM_PCHAN_TCH_F_PDCH, which is now handled in ts_pchan(). Explicitly add GSM_PCHAN_PDCH as zero in subslots_per_pchan[] (cosmetic). Adjust the comment in subslots_per_pchan[]. The fix for the number of subslots affects only one caller: bts_chan_load() in chan_alloc.c. Before this, it would always include a TCH/F_PDCH in the load_counter->total, now it is skipped when in PDCH mode. Whether this is the way bts_chan_load() should handle dynamic TS is a separate discussion, so far I'm only making sure that the two dyn TS kinds act in the same way: TCH/F_TCH/H_PDCH is only counted when in TCH mode, and TCH/F_PDCH should match. Change-Id: Icd6668667ad2be7ad20866ffd185bf3b8711ccd6 --- M openbsc/src/libcommon/gsm_data_shared.c M openbsc/tests/channel/channel_test.c 2 files changed, 21 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index c8c9e04..371e479 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -712,24 +712,38 @@ static const uint8_t subslots_per_pchan[] = { [GSM_PCHAN_NONE] = 0, [GSM_PCHAN_CCCH] = 0, + [GSM_PCHAN_PDCH] = 0, [GSM_PCHAN_CCCH_SDCCH4] = 4, [GSM_PCHAN_TCH_F] = 1, [GSM_PCHAN_TCH_H] = 2, [GSM_PCHAN_SDCCH8_SACCH8C] = 8, - [GSM_PCHAN_TCH_F_PDCH] = 1, [GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4, [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8, /* - * GSM_PCHAN_TCH_F_TCH_H_PDCH should not be part of this, those TS are - * handled according to their ts->dyn state. + * GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be + * part of this, those TS are handled according to their dynamic state. */ }; + +/*! Return the actual pchan type, also heeding dynamic TS. */ +static enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F_TCH_H_PDCH: + return ts->dyn.pchan_is; + case GSM_PCHAN_TCH_F_PDCH: + if (ts->flags & TS_F_PDCH_ACTIVE) + return GSM_PCHAN_PDCH; + else + return GSM_PCHAN_TCH_F; + default: + return ts->pchan; + } +} /*! According to ts->pchan and possibly ts->dyn_pchan, return the number of * logical channels available in the timeslot. */ uint8_t ts_subslots(struct gsm_bts_trx_ts *ts) { - if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) - return subslots_per_pchan[ts->dyn.pchan_is]; - return subslots_per_pchan[ts->pchan]; + return subslots_per_pchan[ts_pchan(ts)]; } diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 668644d..b4a5fb1 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -109,7 +109,7 @@ ts.flags = 0; /* TCH_F mode */ OSMO_ASSERT(ts_subslots(&ts) == 1); ts.flags = TS_F_PDCH_ACTIVE; - OSMO_ASSERT(ts_subslots(&ts) == 1 /* SHOULD BE 0 */); + OSMO_ASSERT(ts_subslots(&ts) == 0); ts.pchan = GSM_PCHAN_TCH_F_TCH_H_PDCH; ts.dyn.pchan_is = GSM_PCHAN_TCH_F; -- To view, visit https://gerrit.osmocom.org/939 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Icd6668667ad2be7ad20866ffd185bf3b8711ccd6 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:02 +0000 Subject: [MERGED] openbsc[master]: channel_test: test nr of subslots for dyn pchan, with error In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: channel_test: test nr of subslots for dyn pchan, with error ...................................................................... channel_test: test nr of subslots for dyn pchan, with error Add test_dyn_ts_subslots() and call from main(). Update channel_test.ok. This includes erratic assert to show a bug for TCH/F_PDCH in PDCH mode: the nr of subslots should be the same as for a normal PDCH, i.e. zero. This will be adjusted along with the fix in an upcoming commit. Change-Id: I09685be3fb3ed1ead4577b772a9fbc31967980d1 --- M openbsc/tests/channel/channel_test.c M openbsc/tests/channel/channel_test.ok 2 files changed, 32 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 2012832..668644d 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -90,11 +90,42 @@ OSMO_ASSERT(s_end); } +void test_dyn_ts_subslots(void) +{ + struct gsm_bts_trx_ts ts; + + printf("Testing subslot numbers for pchan types\n"); + + ts.pchan = GSM_PCHAN_TCH_F; + OSMO_ASSERT(ts_subslots(&ts) == 1); + + ts.pchan = GSM_PCHAN_TCH_H; + OSMO_ASSERT(ts_subslots(&ts) == 2); + + ts.pchan = GSM_PCHAN_PDCH; + OSMO_ASSERT(ts_subslots(&ts) == 0); + + ts.pchan = GSM_PCHAN_TCH_F_PDCH; + ts.flags = 0; /* TCH_F mode */ + OSMO_ASSERT(ts_subslots(&ts) == 1); + ts.flags = TS_F_PDCH_ACTIVE; + OSMO_ASSERT(ts_subslots(&ts) == 1 /* SHOULD BE 0 */); + + ts.pchan = GSM_PCHAN_TCH_F_TCH_H_PDCH; + ts.dyn.pchan_is = GSM_PCHAN_TCH_F; + OSMO_ASSERT(ts_subslots(&ts) == 1); + ts.dyn.pchan_is = GSM_PCHAN_TCH_H; + OSMO_ASSERT(ts_subslots(&ts) == 2); + ts.dyn.pchan_is = GSM_PCHAN_PDCH; + OSMO_ASSERT(ts_subslots(&ts) == 0); +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); test_request_chan(); + test_dyn_ts_subslots(); return EXIT_SUCCESS; } diff --git a/openbsc/tests/channel/channel_test.ok b/openbsc/tests/channel/channel_test.ok index 7976aee..33c8193 100644 --- a/openbsc/tests/channel/channel_test.ok +++ b/openbsc/tests/channel/channel_test.ok @@ -1,2 +1,3 @@ Testing the gsm_subscriber chan logic Reached, didn't crash, test passed +Testing subslot numbers for pchan types -- To view, visit https://gerrit.osmocom.org/937 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I09685be3fb3ed1ead4577b772a9fbc31967980d1 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:03 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:03 +0000 Subject: [MERGED] openbsc[master]: Revert "bts: extend bts_chan_load to allow counting tch only" In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Revert "bts: extend bts_chan_load to allow counting tch only" ...................................................................... Revert "bts: extend bts_chan_load to allow counting tch only" This reverts commit 308cb0719dca3ba8eed1eff2a2124d44f34d9a28. Problems in this commit: openbsc/src/libbsc/chan_alloc.c:523: case GSM_PCHAN_TCH_F_PDCH: This is actually wrong, GSM_PCHAN_TCH_F_PDCH use ts->flags, not ts->dyn below (due to historical reasons and could be unified). 560: if (only_count_tch && !chan_is_tch(ts)) This has exactly one effect: it excludes GSM_PCHAN_TCH_F_PDCH when in PDCH mode, because for all other PDCH (plain PDCH and TCH/F_TCH/H_PDCH in PDCH mode) below ts_subslots() returns 0 and skips the for() loop. I consider this a bug in TCH/F_PDCH, to be fixed in an upcoming commit. I don't see why we need the only_count_tch argument, because this should normally only count TCH, weren't it for the TCH/F_PDCH bug. If dyn TS should be counted differently, we should do this in a different way. Change-Id: I34dbbaf53a800115e3d03bd44028cad675f3b525 --- M openbsc/include/openbsc/chan_alloc.h M openbsc/src/libbsc/bsc_ctrl_commands.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/chan_alloc.c M openbsc/src/libbsc/paging.c 5 files changed, 7 insertions(+), 30 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h index d919b51..78242e5 100644 --- a/openbsc/include/openbsc/chan_alloc.h +++ b/openbsc/include/openbsc/chan_alloc.h @@ -46,7 +46,7 @@ struct load_counter pchan[_GSM_PCHAN_MAX]; }; -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, int only_count_tch); +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts); void network_chan_load(struct pchan_load *pl, struct gsm_network *net); int trx_is_usable(struct gsm_bts_trx *trx); diff --git a/openbsc/src/libbsc/bsc_ctrl_commands.c b/openbsc/src/libbsc/bsc_ctrl_commands.c index 3f4fee2..7e84797 100644 --- a/openbsc/src/libbsc/bsc_ctrl_commands.c +++ b/openbsc/src/libbsc/bsc_ctrl_commands.c @@ -239,7 +239,7 @@ bts = cmd->node; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); cmd->reply = talloc_strdup(cmd, ""); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index cdcc011..cb0b1d8 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -329,7 +329,7 @@ /* FIXME: chan_desc */ memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE); dump_pchan_load_vty(vty, " ", &pl); } diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c index 03d44e0..7b0c3e6 100644 --- a/openbsc/src/libbsc/chan_alloc.c +++ b/openbsc/src/libbsc/chan_alloc.c @@ -514,28 +514,7 @@ return NULL; } -static int chan_is_tch(struct gsm_bts_trx_ts *ts) -{ - switch (ts->pchan) { - case GSM_PCHAN_TCH_F: - case GSM_PCHAN_TCH_H: - return 1; - case GSM_PCHAN_TCH_F_PDCH: - case GSM_PCHAN_TCH_F_TCH_H_PDCH: - if (ts->dyn.pchan_is == GSM_PCHAN_TCH_F || - ts->dyn.pchan_is == GSM_PCHAN_TCH_H) - return 1; - else - return 0; - default: - return 0; - } -} - - - -void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts, - int only_count_tch) +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts) { struct gsm_bts_trx *trx; @@ -555,9 +534,6 @@ /* skip administratively deactivated timeslots */ if (!nm_is_running(&ts->mo.nm_state)) - continue; - - if (only_count_tch && !chan_is_tch(ts)) continue; subslots = ts_subslots(ts); @@ -585,5 +561,6 @@ memset(pl, 0, sizeof(*pl)); llist_for_each_entry(bts, &net->bts_list, list) - bts_chan_load(pl, bts, 0); + bts_chan_load(pl, bts); } + diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index e3795b3..fcb4deb 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -119,7 +119,7 @@ int count; memset(&pl, 0, sizeof(pl)); - bts_chan_load(&pl, bts, 0); + bts_chan_load(&pl, bts); switch (rsl_type) { case RSL_CHANNEED_TCH_F: -- To view, visit https://gerrit.osmocom.org/938 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I34dbbaf53a800115e3d03bd44028cad675f3b525 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:28:03 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:28:03 +0000 Subject: [MERGED] openbsc[master]: channel test: prepare to add another test function In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: channel test: prepare to add another test function ...................................................................... channel test: prepare to add another test function Move the main() guts to test_request_chan(), so that I can add another test in an upcoming commit. Change-Id: I1349d0f416806416080d4667ad697f7db1ea252d --- M openbsc/tests/channel/channel_test.c 1 file changed, 8 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 924d763..2012832 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -58,12 +58,10 @@ } -int main(int argc, char **argv) +void test_request_chan(void) { struct gsm_network *network; struct gsm_bts *bts; - - osmo_init_logging(&log_info); printf("Testing the gsm_subscriber chan logic\n"); @@ -90,6 +88,13 @@ s_cbfn(101, 200, (void*)0x1323L, &s_conn, s_data); OSMO_ASSERT(s_end); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&log_info); + + test_request_chan(); return EXIT_SUCCESS; } -- To view, visit https://gerrit.osmocom.org/936 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1349d0f416806416080d4667ad697f7db1ea252d Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:29:18 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:29:18 +0000 Subject: libosmocore[master]: AMR: add function to check speech frames In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/959/1/src/codec/gsm690.c File src/codec/gsm690.c: Line 242: bool osmo_amr_is_speech(enum osmo_amr_type ft) might make sense to have this as an inline function in the header file, given it s simplicity and high usage frequency (probably at least once for each RTP frame processed, maybe more). -- To view, visit https://gerrit.osmocom.org/959 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:31:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:31:42 +0000 Subject: libosmocore[master]: osmo_select_main(): drop useless call to osmo_timers_check() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/872 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8d35ca90a4c16d6f1c7f9793d663e5479783efed Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 00:47:28 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 00:47:28 +0000 Subject: [MERGED] openbsc[master]: COSMETIC: 'if' is not a function, so there is space before '(' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: COSMETIC: 'if' is not a function, so there is space before '(' ...................................................................... COSMETIC: 'if' is not a function, so there is space before '(' Change-Id: Ic22623dffce998d70a3c67aa6e445de98f558ed7 --- M openbsc/src/gprs/gprs_llc.c M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/sgsn_libgtp.c M openbsc/src/libmgcp/mgcp_protocol.c M openbsc/src/osmo-bsc/osmo_bsc_sccp.c 5 files changed, 7 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index ff771b8..5b1f333 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -1066,7 +1066,7 @@ /* Generate XID message */ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),llme->iov_ui,llme); - if(xid_bytes_len < 0) + if (xid_bytes_len < 0) return -EINVAL; xid = msgb_put(msg, xid_bytes_len); memcpy(xid, xid_bytes, xid_bytes_len); @@ -1099,7 +1099,7 @@ /* Generate XID message */ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),llme->iov_ui,llme); - if(xid_bytes_len < 0) + if (xid_bytes_len < 0) return -EINVAL; xid = msgb_put(msg, xid_bytes_len); memcpy(xid, xid_bytes, xid_bytes_len); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 0b18f81..1cbeede 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -779,7 +779,7 @@ /* FIXME: move this RA_ID up to the LLME or even higher */ bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); - if(scomph) { + if (scomph) { sne->defrag.pcomp = scomph->pcomp; sne->defrag.dcomp = scomph->dcomp; sne->defrag.proto = lle->llme->comp.proto; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 9f65325..127ee30 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -328,13 +328,13 @@ /* Send PDP CTX ACT to MS */ rc = gsm48_tx_gsm_act_pdp_acc(pctx); - if(rc < 0) + if (rc < 0) return rc; /* Send SNDCP XID to MS */ lle = &pctx->mm->gb.llme->lle[pctx->sapi]; rc = sndcp_sn_xid_req(lle,pctx->nsapi); - if(rc < 0) + if (rc < 0) return rc; return 0; diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index ff0fc3e..2e728cb 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -818,7 +818,7 @@ if (osmux_cid >= 0) { endp->osmux.cid = osmux_cid; endp->osmux.state = OSMUX_STATE_NEGOTIATING; - } else if(endp->cfg->osmux == OSMUX_USAGE_ONLY) { + } else if (endp->cfg->osmux == OSMUX_USAGE_ONLY) { LOGP(DMGCP, LOGL_ERROR, "Osmux only and no osmux offered on 0x%x\n", ENDPOINT_NUMBER(endp)); goto error2; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c index 33c737f..86b27be 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c @@ -80,7 +80,7 @@ if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) { con_data = (struct osmo_bsc_sccp_con *) conn->data_ctx; - if(con_data->conn) { + if (con_data->conn) { LOGP(DMSC, LOGL_ERROR, "ERROR: The lchan is still associated.\n"); gsm0808_clear(con_data->conn); -- To view, visit https://gerrit.osmocom.org/962 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic22623dffce998d70a3c67aa6e445de98f558ed7 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 08:41:56 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 28 Sep 2016 08:41:56 +0000 Subject: [PATCH] libosmocore[master]: AMR: add function to check speech frames In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/959 to look at the new patch set (#2). AMR: add function to check speech frames Add convenience function osmo_amr_is_speech() to check if given AMR frame is speech frame: non-speech frames often require special processing. Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 --- M include/osmocom/codec/codec.h 1 file changed, 21 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/59/959/2 diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index f7a8ad9..74eca46 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -42,6 +42,27 @@ AMR_GOOD = 1 }; +/*! \brief Check if given AMR Frame Type is a speech frame + * \param[in] ft AMR Frame Type + * \returns true if AMR with given Frame Type contains voice, false otherwise + */ +inline bool osmo_amr_is_speech(enum osmo_amr_type ft) +{ + switch (ft) { + case AMR_4_75: + case AMR_5_15: + case AMR_5_90: + case AMR_6_70: + case AMR_7_40: + case AMR_7_95: + case AMR_10_2: + case AMR_12_2: + return true; + default: + return false; + } +} + bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len); bool osmo_hr_check_sid(uint8_t *rtp_payload, size_t payload_len); int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft, -- To view, visit https://gerrit.osmocom.org/959 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 09:39:27 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 09:39:27 +0000 Subject: [PATCH] openbsc[master]: SGSN: Fixing build config Message-ID: Review at https://gerrit.osmocom.org/963 SGSN: Fixing build config Tests for V.42bis, slhc, llc-xid and sndcp-xid are built and executed on all build configurations, but are only needed when the sgsn (gprs) is built. This patch adds conditions check if the tests mentioned abvove are needed or not. Change-Id: I6921e6198ea7f99fe5276f91cbc522091853bc4e --- M openbsc/tests/Makefile.am M openbsc/tests/testsuite.at 2 files changed, 8 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/63/963/1 diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 0ebd2e2..468edd2 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -9,10 +9,6 @@ trau \ subscr \ mm_auth \ - xid \ - sndcp_xid \ - slhc \ - v42bis \ $(NULL) if BUILD_NAT @@ -40,6 +36,10 @@ SUBDIRS += \ sgsn \ oap \ + xid \ + sndcp_xid \ + slhc \ + v42bis \ $(NULL) endif endif diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index f18b734..4905cd1 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -126,24 +126,28 @@ AT_SETUP([xid]) AT_KEYWORDS([xid]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/xid/xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([sndcp_xid]) AT_KEYWORDS([sndcp_xid]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([slhc]) AT_KEYWORDS([slhc]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/slhc/slhc_test.ok > expout AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([v42bis]) AT_KEYWORDS([v42bis]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/v42bis/v42bis_test.ok > expout AT_CHECK([$abs_top_builddir/tests/v42bis/v42bis_test], [], [expout], [ignore]) AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/963 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6921e6198ea7f99fe5276f91cbc522091853bc4e Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Sep 28 09:46:35 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 28 Sep 2016 09:46:35 +0000 Subject: [PATCH] osmo-bts[master]: DTX: further SID caching fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/960 to look at the new patch set (#2). DTX: further SID caching fixes (lc15, sysmo) * consolidate AMR CMR and CMI handling in common/amr.c * use it in save_last_sid() * remove dead code * properly compute RTP payload length for AMR * use save_last_sid() for FR & HR as well * invalidate cached SID if SPEECH frame is received Fixes: OS #1800, #1801 Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed --- M include/osmo-bts/amr.h M include/osmo-bts/msg_utils.h M src/common/amr.c M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 6 files changed, 129 insertions(+), 173 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/60/960/2 diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index 6bdc41f..f313287 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -11,7 +11,8 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, const uint8_t *mr_conf, unsigned int len); -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi); +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f03eb43..456ff3c 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -24,8 +24,9 @@ }; void lchan_set_marker(bool t, struct gsm_lchan *lchan); -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/common/amr.c b/src/common/amr.c index 56ed430..b5d2c37 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -22,7 +22,8 @@ LOGPC(ss, logl, "\n"); } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) +static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) { unsigned int i; for (i = 0; i < amr_mrc->num_modes; i++) { @@ -32,6 +33,46 @@ return -EINVAL; } +static inline uint8_t set_cmr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmr) +{ + int rc; + + /* Codec Mode Request is in upper 4 bits of RTP payload header, + * and we simply copy the CMR into the CMC */ + if (cmr == 0xF) { + /* FIXME: we need some state about the last codec mode */ + return 0; + } + + rc = get_amr_mode_idx(amr_mrc, cmr); + if (rc < 0) { + /* FIXME: we need some state about the last codec mode */ + LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); + return 0; + } + return rc; +} + +static inline uint8_t set_cmi_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) +{ + int rc = get_amr_mode_idx(amr_mrc, cmi); + if (rc < 0) { + LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", + cmi); + return 0; + } + return rc; +} + +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr) +{ + data[0] = set_cmi_mode_idx(amr_mrc, cmi); + data[1] = set_cmr_mode_idx(amr_mrc, cmr); +} + /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more * comfortable internal data structure */ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 967b10d..ae2dd28 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -99,17 +100,30 @@ } /* store the last SID frame in lchan context */ -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) +/*! \brief Store the last SID frame in lchan context + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] l1_payload buffer with SID data + * \param[in] length length of l1_payload + * \param[in] fn Frame Number for which we check scheduling + * \param[in] update 0 if SID_FIRST, 1 if SID_UPDATE, -1 if not AMR SID + * \param[in] cmr Codec Mode Request (AMR-specific, ignored otherwise) + * \param[in] cmi Codec Mode Indication (AMR-specific, ignored otherwise) + */ +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi) { - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); + size_t amr = (update < 0) ? 0 : 2, + copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; + lchan->tch.last_sid.len = copy_len + amr; lchan->tch.last_sid.fn = fn; lchan->tch.last_sid.is_update = update; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); + if (amr) + amr_set_mode_pref(lchan->tch.last_sid.buf, &lchan->tch.amr_mr, + cmi, cmr); + memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } /* repeat last SID if possible, returns SID length + 1 or 0 */ diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index bcf981e..2fd935e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,85 +200,12 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); memcpy(l1_payload+2, rtp_payload, payload_len); + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -305,6 +232,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -318,32 +246,54 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index f350398..714570c 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,19 +283,8 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - #ifdef USE_L1_RTP_MODE memcpy(l1_payload+2, rtp_payload, payload_len); #else @@ -310,72 +299,9 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -402,6 +328,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -415,34 +342,56 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; #endif case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 10:33:58 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 10:33:58 +0000 Subject: libosmocore[master]: AMR: add function to check speech frames In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/959 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 10:34:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 28 Sep 2016 10:34:02 +0000 Subject: [MERGED] libosmocore[master]: AMR: add function to check speech frames In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: AMR: add function to check speech frames ...................................................................... AMR: add function to check speech frames Add convenience function osmo_amr_is_speech() to check if given AMR frame is speech frame: non-speech frames often require special processing. Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 --- M include/osmocom/codec/codec.h 1 file changed, 21 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index f7a8ad9..74eca46 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -42,6 +42,27 @@ AMR_GOOD = 1 }; +/*! \brief Check if given AMR Frame Type is a speech frame + * \param[in] ft AMR Frame Type + * \returns true if AMR with given Frame Type contains voice, false otherwise + */ +inline bool osmo_amr_is_speech(enum osmo_amr_type ft) +{ + switch (ft) { + case AMR_4_75: + case AMR_5_15: + case AMR_5_90: + case AMR_6_70: + case AMR_7_40: + case AMR_7_95: + case AMR_10_2: + case AMR_12_2: + return true; + default: + return false; + } +} + bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len); bool osmo_hr_check_sid(uint8_t *rtp_payload, size_t payload_len); int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft, -- To view, visit https://gerrit.osmocom.org/959 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifaab02a2f581acc302b367d34fd2fc28a4d1e2e3 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 10:37:53 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 10:37:53 +0000 Subject: [PATCH] osmo-bts[master]: octphy: set tx attenuation via VTY In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/905 to look at the new patch set (#3). octphy: set tx attenuation via VTY add code to configure the transmision power via VTY Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 --- M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c M src/osmo-bts-octphy/octphy_vty.c 3 files changed, 30 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/05/905/3 diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index ea0fb33..7c09b2d 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -62,6 +62,7 @@ /* configuration */ uint32_t rf_port_index; uint32_t rx_gain_db; + uint32_t tx_atten_flag; uint32_t tx_atten_db; struct octphy_hdl *hdl; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 7735261..4579df7 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1349,7 +1349,14 @@ oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; /* FIXME: compute this based on nominal transmit power, etc. */ - oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + if (plink->u.octphy.tx_atten_flag == 1) { + oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + } + else { + /* Take the Tx Attn received in set radio attribures + * x4 is for the value in db */ + oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; + } LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "tsc=%u, rx_gain=%u, tx_atten=%u)\n", diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index 3ea576c..53099c8 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -135,6 +135,24 @@ return CMD_SUCCESS; } +DEFUN(cfg_phy_tx_atten_flag, cfg_phy_tx_atten_flag_cmd, + "octphy tx-attenuation-flag <0-1>", + OCT_STR "1 - Use config file to set Tx Attenuation\n" + "Use config file to set Tx Attenuation\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.tx_atten_flag = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_phy_tx_atten_db, cfg_phy_tx_atten_db_cmd, "octphy tx-attenuation <0-359>", OCT_STR "Configure the Tx Attenuation in quarter-dB\n" @@ -202,6 +220,8 @@ VTY_NEWLINE); vty_out(vty, " rx-gain %u%s", plink->u.octphy.rx_gain_db, VTY_NEWLINE); + vty_out(vty, " tx-attenuation-flag %u%s", plink->u.octphy.tx_atten_flag, + VTY_NEWLINE); vty_out(vty, " tx-attenuation %u%s", plink->u.octphy.tx_atten_db, VTY_NEWLINE); vty_out(vty, " rf-port-index %u%s", plink->u.octphy.rf_port_index, @@ -250,6 +270,7 @@ install_element(PHY_NODE, &cfg_phy_netdev_cmd); install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); + install_element(PHY_NODE, &cfg_phy_tx_atten_flag_cmd); install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); install_element_ve(&show_rf_port_stats_cmd); -- To view, visit https://gerrit.osmocom.org/905 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 10:37:53 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 10:37:53 +0000 Subject: [PATCH] osmo-bts[master]: octphy: Fixed OML ADM state handling In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/906 to look at the new patch set (#3). octphy: Fixed OML ADM state handling bts_model_chg_adm_state() is accepting all state changes blindly, this patch adds a proper state handling Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 71 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/06/906/3 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 4579df7..e543c15 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -50,6 +50,8 @@ #include #include +int trx_locked = 0; + /* Map OSMOCOM logical channel type to OctPHY Logical channel type */ static tOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM pchan_to_logChComb[_GSM_PCHAN_MAX] = { @@ -1509,10 +1511,75 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state) { - /* TODO: implement this properly */ - /* blindly accept all state changes */ - mo->nm_state.administrative = adm_state; - return oml_mo_statechg_ack(mo); + int rc; + int granted = 0; + + struct gsm_bts_trx *trx; + struct phy_instance *pinst; + struct octphy_hdl *fl1h; + + switch (mo->obj_class) { + case NM_OC_RADIO_CARRIER: + + trx = ((struct gsm_bts_trx *)obj); + pinst = trx_phy_instance(trx); + fl1h = pinst->phy_link->u.octphy.hdl; + + if (mo->procedure_pending) { + LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: " + "pending procedure on RC %d\n", trx->nr); + return 0; + } + mo->procedure_pending = 1; + switch (adm_state) { + case NM_STATE_LOCKED: + + trx_locked = 1; + + /* Stop heartbeat check */ + osmo_timer_del(&fl1h->alive_timer); + + bts_model_trx_deact_rf(trx); + + /* Close TRX */ + rc = bts_model_trx_close(trx); + if (rc != 0) { + LOGP(DL1C, LOGL_ERROR, + "TRX already closed..!\n\n"); + } + granted = 1; + break; + + case NM_STATE_UNLOCKED: + + if (trx_locked) { + trx_locked = 0; + l1if_activate_rf(trx, 1); + } + + granted = 1; + break; + + default: + granted = 1; + break; + } + + mo->procedure_pending = 0; + break; + + default: + /* blindly accept all state changes */ + granted = 1; + break; + } + + if (granted) { + mo->nm_state.administrative = adm_state; + return oml_mo_statechg_ack(mo); + } else + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) -- To view, visit https://gerrit.osmocom.org/906 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 10:48:46 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 10:48:46 +0000 Subject: [MERGED] libosmocore[master]: osmo_select_main(): drop useless call to osmo_timers_check() In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: osmo_select_main(): drop useless call to osmo_timers_check() ...................................................................... osmo_select_main(): drop useless call to osmo_timers_check() osmo_timers_check() does nothing more than counting the active timers. It is of no use to count them when not using the return value in any way. Change-Id: I8d35ca90a4c16d6f1c7f9793d663e5479783efed --- M src/select.c 1 file changed, 0 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/select.c b/src/select.c index 192cae2..da27368 100644 --- a/src/select.c +++ b/src/select.c @@ -176,8 +176,6 @@ /* prepare read and write fdsets */ osmo_fd_fill_fds(&readset, &writeset, &exceptset); - osmo_timers_check(); - if (!polling) osmo_timers_prepare(); rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : osmo_timers_nearest()); -- To view, visit https://gerrit.osmocom.org/872 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8d35ca90a4c16d6f1c7f9793d663e5479783efed Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 11:36:22 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 11:36:22 +0000 Subject: [PATCH] osmo-bts[master]: common: Improvements for channel measurement reporting In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/901 to look at the new patch set (#3). common: Improvements for channel measurement reporting This was handed in by octasic. The particular purpose of this is unclear to me. Please leave a comment on how to proceed with this. Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 --- M src/common/measurement.c 1 file changed, 6 insertions(+), 50 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/01/901/3 diff --git a/src/common/measurement.c b/src/common/measurement.c index be1d4f6..8c1012b 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -71,15 +71,11 @@ break; case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: - fn_mod = fn % 102; - if (fn_mod == 11) - rc = 1; + rc = 1; break; case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4_CBCH: - fn_mod = fn % 102; - if (fn_mod == 36) - rc = 1; + rc = 1; break; default: rc = 0; @@ -135,13 +131,6 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) { struct gsm_meas_rep_unidir *mru; - uint32_t ber_full_sum = 0; - uint32_t irssi_full_sum = 0; - uint32_t ber_sub_sum = 0; - uint32_t irssi_sub_sum = 0; - int32_t taqb_sum = 0; - unsigned int num_meas_sub = 0; - int i; /* if measurement period is not complete, abort */ if (!is_meas_complete(lchan->ts->pchan, lchan->ts->nr, @@ -152,45 +141,12 @@ if (lchan->meas.num_ul_meas == 0) return 0; - /* compute the actual measurements */ - - /* step 1: add up */ - for (i = 0; i < lchan->meas.num_ul_meas; i++) { - struct bts_ul_meas *m = &lchan->meas.uplink[i]; - - ber_full_sum += m->ber10k; - irssi_full_sum += m->inv_rssi; - taqb_sum += m->ta_offs_qbits; - - if (m->is_sub) { - num_meas_sub++; - ber_sub_sum += m->ber10k; - irssi_sub_sum += m->inv_rssi; - } - } - - /* step 2: divide */ - ber_full_sum = ber_full_sum / lchan->meas.num_ul_meas; - irssi_full_sum = irssi_full_sum / lchan->meas.num_ul_meas; - taqb_sum = taqb_sum / lchan->meas.num_ul_meas; - - if (num_meas_sub) { - ber_sub_sum = ber_sub_sum / num_meas_sub; - irssi_sub_sum = irssi_sub_sum / num_meas_sub; - } - - DEBUGP(DMEAS, "%s Computed TA(% 4dqb) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), " - "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", gsm_lchan_name(lchan), - taqb_sum, ber_full_sum/100, - ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100, - irssi_sub_sum); - /* store results */ mru = &lchan->meas.ul_res; - mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1); - mru->sub.rx_lev = dbm2rxlev((int)irssi_sub_sum * -1); - mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum); - mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum); + mru->full.rx_lev = lchan->meas.uplink[0].inv_rssi; + mru->sub.rx_lev = lchan->meas.uplink[0].inv_rssi; + mru->full.rx_qual = (uint8_t)lchan->meas.uplink[0].ber10k; + mru->sub.rx_qual = (uint8_t)lchan->meas.uplink[0].ber10k; lchan->meas.flags |= LC_UL_M_F_RES_VALID; lchan->meas.num_ul_meas = 0; -- To view, visit https://gerrit.osmocom.org/901 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 11:36:22 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 11:36:22 +0000 Subject: [PATCH] osmo-bts[master]: rsl: improved log output improving the log output In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/902 to look at the new patch set (#3). rsl: improved log output improving the log output to show more details about the payload type and the connection Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd --- M src/common/rsl.c 1 file changed, 13 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/02/902/3 diff --git a/src/common/rsl.c b/src/common/rsl.c index 493ff3b..d3893f7 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1584,21 +1584,27 @@ return tx_ipac_XXcx_nack(lchan, RSL_ERR_MAND_IE_ERROR, 0, dch->c.msg_type); - /* any of these can be NULL!! */ - speech_mode = TLVP_VAL(&tp, RSL_IE_IPAC_SPEECH_MODE); - payload_type = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD); - payload_type2 = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD2); - - if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_IP)) + if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_IP)) { connect_ip = tlvp_val32_unal(&tp, RSL_IE_IPAC_REMOTE_IP); + LOGP(DRSL, LOGL_NOTICE, "connect_ip %d \n", connect_ip ); + } else LOGP(DRSL, LOGL_NOTICE, "CRCX does not specify a remote IP\n"); - if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_PORT)) + if (TLVP_PRESENT(&tp, RSL_IE_IPAC_REMOTE_PORT)) { connect_port = tlvp_val16_unal(&tp, RSL_IE_IPAC_REMOTE_PORT); + LOGP(DRSL, LOGL_NOTICE, "connect_port %d \n", connect_port ); + } else LOGP(DRSL, LOGL_NOTICE, "CRCX does not specify a remote port\n"); + /* any of these can be NULL!! */ + speech_mode = TLVP_VAL(&tp, RSL_IE_IPAC_SPEECH_MODE); + LOGP(DRSL, LOGL_NOTICE, "speech_mode %d \n",*speech_mode ); + payload_type = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD); + LOGP(DRSL, LOGL_NOTICE, "Pay load type %d \n",*payload_type ); + payload_type2 = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD2); + if (dch->c.msg_type == RSL_MT_IPAC_CRCX && connect_ip && connect_port) inc_ip_port = 1; -- To view, visit https://gerrit.osmocom.org/902 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 12:55:05 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 12:55:05 +0000 Subject: [PATCH] openbsc[master]: fix: send SNDCP XID only on GERAN Gb contexts Message-ID: Review at https://gerrit.osmocom.org/964 fix: send SNDCP XID only on GERAN Gb contexts Add a condition for GERAN Gb. SNDCP and IuPS were developed on separate branches, and the merge results in code trying to use an llme on a UTRAN Iu context where the llme is NULL, leading to stack corruption upon PDP ctx act. Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 --- M openbsc/src/gprs/sgsn_libgtp.c 1 file changed, 7 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/64/964/1 diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 127ee30..29c9f06 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -331,11 +331,13 @@ if (rc < 0) return rc; - /* Send SNDCP XID to MS */ - lle = &pctx->mm->gb.llme->lle[pctx->sapi]; - rc = sndcp_sn_xid_req(lle,pctx->nsapi); - if (rc < 0) - return rc; + if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if (rc < 0) + return rc; + } return 0; } -- To view, visit https://gerrit.osmocom.org/964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 13:17:47 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 13:17:47 +0000 Subject: openbsc[master]: fix: send SNDCP XID only on GERAN Gb contexts In-Reply-To: References: Message-ID: Patch Set 1: failure due to rename in libosmo-sccp's iu branch, fixed by osmo-iuh f41b2fa500c209136c3446f4bc9d9da348539f92 -- To view, visit https://gerrit.osmocom.org/964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 13:18:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 13:18:45 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/866 to look at the new patch set (#6). jenkins.sh: output all test logs when 'make check' failed Assume that cat-testlogs.sh from osmo-ci is installed in $HOME/osmo-ci/scripts, and call from jenkins.sh upon 'make check' failure. Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- M contrib/jenkins.sh 1 file changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/866/6 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e9f63e4 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 13:18:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 13:18:58 +0000 Subject: libosmocore[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Sep 28 13:21:41 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 28 Sep 2016 13:21:41 +0000 Subject: [PATCH] openbsc[master]: sndcp: Fixups for sndcp layer based on coverity-scan suggest... Message-ID: Review at https://gerrit.osmocom.org/965 sndcp: Fixups for sndcp layer based on coverity-scan suggestions - missing break in gprs_sndcp_pcomp.c, line 143 - string overflow in slhc_test.c, line 211 - sizeof mismatch in gprs_sndcp_xid.c, line 1369 and 1378 - mismatching signedness in gprs_sndcp_xid.c, line 1377 - needless < 0 comparison in gprs_sndcp_xid.c, line 477 - needless < 0 comparison in gprs_sndcp_xid.c, line 209 - missing returncode check in v42bis_test.c, line 320 - wrong pointer dereferentialization in gprs_sndcp_comp.c, line 73 Change-Id: I4f9adf251f5119e67ffe76baad6f1f996ac8dbad --- M openbsc/src/gprs/gprs_sndcp.c M openbsc/src/gprs/gprs_sndcp_comp.c M openbsc/src/gprs/gprs_sndcp_pcomp.c M openbsc/src/gprs/gprs_sndcp_xid.c M openbsc/tests/slhc/slhc_test.c M openbsc/tests/v42bis/v42bis_test.c 6 files changed, 13 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/65/965/1 diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index 1cbeede..59a9cd4 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -41,7 +41,7 @@ #include #include -#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ +#define DEBUG_IP_PACKETS 1 /* 0=Disabled, 1=Enabled */ #if DEBUG_IP_PACKETS == 1 /* Calculate TCP/IP checksum */ diff --git a/openbsc/src/gprs/gprs_sndcp_comp.c b/openbsc/src/gprs/gprs_sndcp_comp.c index b13cb8b..cae0039 100644 --- a/openbsc/src/gprs/gprs_sndcp_comp.c +++ b/openbsc/src/gprs/gprs_sndcp_comp.c @@ -70,7 +70,7 @@ comp_field->v42bis_params->nsapi, sizeof(comp_entity->nsapi)); } else if (comp_field->v44_params) { - comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; + comp_entity->nsapi_len = comp_field->v44_params->nsapi_len; memcpy(comp_entity->nsapi, comp_field->v42bis_params->nsapi, sizeof(comp_entity->nsapi)); diff --git a/openbsc/src/gprs/gprs_sndcp_pcomp.c b/openbsc/src/gprs/gprs_sndcp_pcomp.c index 5f6fb2c..493b263 100644 --- a/openbsc/src/gprs/gprs_sndcp_pcomp.c +++ b/openbsc/src/gprs/gprs_sndcp_pcomp.c @@ -141,6 +141,7 @@ switch (pcomp_index) { case 0: type = SL_TYPE_IP; + break; case 1: type = SL_TYPE_UNCOMPRESSED_TCP; break; diff --git a/openbsc/src/gprs/gprs_sndcp_xid.c b/openbsc/src/gprs/gprs_sndcp_xid.c index 270bdee..a4f9442 100644 --- a/openbsc/src/gprs/gprs_sndcp_xid.c +++ b/openbsc/src/gprs/gprs_sndcp_xid.c @@ -206,7 +206,6 @@ /* Bail if number of ROHC profiles exceeds limit * (ROHC supports only a maximum of 16 different profiles) */ - OSMO_ASSERT(params->profile_len >= 0); OSMO_ASSERT(params->profile_len <= 16); /* Zero out buffer */ @@ -475,8 +474,7 @@ for (i = 0; i < comp_field->comp_len; i++) { /* Check if submitted PCOMP/DCOMP values are within bounds */ - if ((comp_field->comp[i] < 0) - || (comp_field->comp[i] > 0x0F)) + if (comp_field->comp[i] > 0x0F) return -EINVAL; if (i & 1) { @@ -1360,25 +1358,27 @@ { struct gprs_sndcp_comp_field *comp_field; int i = 0; + int rc; if (!comp_fields) return -EINVAL; if (!lt) return -EINVAL; - memset(lt, 0, lt_len * sizeof(lt)); + memset(lt, 0, sizeof(*lt)); llist_for_each_entry(comp_field, comp_fields, list) { lt[i].entity = comp_field->entity; lt[i].algo = comp_field->algo; - lt[i].compclass = gprs_sndcp_get_compression_class(comp_field); + rc = gprs_sndcp_get_compression_class(comp_field); - if (lt[i].compclass < 0) { - memset(lt, 0, lt_len * sizeof(lt)); + if (rc < 0) { + memset(lt, 0, sizeof(*lt)); return -EINVAL; } + lt[i].compclass = rc; i++; } diff --git a/openbsc/tests/slhc/slhc_test.c b/openbsc/tests/slhc/slhc_test.c index e8ea02f..d2e1cd9 100644 --- a/openbsc/tests/slhc/slhc_test.c +++ b/openbsc/tests/slhc/slhc_test.c @@ -182,6 +182,8 @@ memset(packet, 0, sizeof(packet)); memset(packet_compr, 0, sizeof(packet_compr)); memset(packet_decompr, 0, sizeof(packet_decompr)); + + OSMO_ASSERT(strlen(packets[i]) < sizeof(packet_ascii)); strcpy(packet_ascii, packets[i]); packet_len = diff --git a/openbsc/tests/v42bis/v42bis_test.c b/openbsc/tests/v42bis/v42bis_test.c index 4e05514..7e90785 100644 --- a/openbsc/tests/v42bis/v42bis_test.c +++ b/openbsc/tests/v42bis/v42bis_test.c @@ -318,6 +318,7 @@ len = strlen(uncompr_packets[packet_id]); testvec = talloc_zero_size(ctx, len); len = osmo_hexparse(uncompr_packets[packet_id], testvec, len); + OSMO_ASSERT(len > 0); v42bis(ctx, V42BIS_COMPRESSION_MODE_DYNAMIC, testvec, len); v42bis(ctx, V42BIS_COMPRESSION_MODE_ALWAYS, testvec, len); v42bis(ctx, V42BIS_COMPRESSION_MODE_NEVER, testvec, len); -- To view, visit https://gerrit.osmocom.org/965 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4f9adf251f5119e67ffe76baad6f1f996ac8dbad Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Sep 28 14:14:49 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 28 Sep 2016 14:14:49 +0000 Subject: [PATCH] libosmocore[master]: Mark inline header function as static Message-ID: Review at https://gerrit.osmocom.org/966 Mark inline header function as static Change-Id: Ib751f7467d54cbcae76f72448a38e30f2ecc63d4 --- M include/osmocom/codec/codec.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/966/1 diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index 74eca46..fb127b5 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -46,7 +46,7 @@ * \param[in] ft AMR Frame Type * \returns true if AMR with given Frame Type contains voice, false otherwise */ -inline bool osmo_amr_is_speech(enum osmo_amr_type ft) +static inline bool osmo_amr_is_speech(enum osmo_amr_type ft) { switch (ft) { case AMR_4_75: -- To view, visit https://gerrit.osmocom.org/966 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib751f7467d54cbcae76f72448a38e30f2ecc63d4 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 28 14:41:55 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 28 Sep 2016 14:41:55 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move scheduling check inside repeat_last_sid Message-ID: Review at https://gerrit.osmocom.org/967 DTX: move scheduling check inside repeat_last_sid Note: this also require changes to properly link against libosmocodec. Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb --- M include/osmo-bts/msg_utils.h M src/common/Makefile.am M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/Makefile.am M src/osmo-bts-sysmo/tch.c M tests/misc/Makefile.am 7 files changed, 64 insertions(+), 79 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/67/967/1 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 456ff3c..f07623d 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -6,6 +6,8 @@ #include +#include + #include struct msgb; @@ -28,7 +30,5 @@ size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index fbb6572..856f741 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS) noinst_LIBRARIES = libbts.a libl1sched.a libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index ae2dd28..4b944dc 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -126,32 +126,13 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } -/* repeat last SID if possible, returns SID length + 1 or 0 */ -/*! \brief Repeat last SID if possible in case of DTX - * \param[in] lchan Logical channel on which we check scheduling - * \param[in] dst Buffer to copy last SID into - * \returns Number of bytes copied + 1 (to accommodate for extra byte with - * payload type) or 0 if there's nothing to copy - */ -uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) -{ - if (lchan->tch.last_sid.len) { - memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); - lchan->tch.last_sid.fn = fn; - return lchan->tch.last_sid.len + 1; - } - LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " - "is empty - sent nothing\n", - get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); - return 0; -} - /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, + uint32_t fn) { /* Compute approx. time delta based on Fn duration */ uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.last_sid.fn); @@ -183,7 +164,7 @@ * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) { /* According to 3GPP TS 45.008 ? 8.3: */ static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, @@ -198,6 +179,42 @@ return false; } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type), 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + /* FIXME: add EFR support */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) + return 0; + + if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { + if (dtx_sched_optional(lchan, fn)) + return 0; + } else + if (dtx_amr_sid_optional(lchan, fn)) + return 0; + + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + return 1 + osmo_amr_rtp_enc(dst, 0, AMR_NO_DATA, AMR_GOOD); + + LOGP(DL1C, LOGL_DEBUG, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + + return 0; +} + /** * Return 0 in case the IPA structure is okay and in this * case the l2h will be set to the beginning of the data. diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index fb3dca7..33545c5 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -451,6 +450,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -465,43 +465,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 34f4bb0..8e39a3a 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -29,7 +29,7 @@ misc/sysmobts_mgr_temp.c \ misc/sysmobts_mgr_calib.c \ eeprom.c -sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a +sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c eeprom.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 879ed33..908ec4c 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -553,6 +552,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -567,43 +567,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am index f60325b..d5acb18 100644 --- a/tests/misc/Makefile.am +++ b/tests/misc/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) noinst_PROGRAMS = misc_test EXTRA_DIST = misc_test.ok -- To view, visit https://gerrit.osmocom.org/967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 28 15:31:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 15:31:22 +0000 Subject: [PATCH] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Message-ID: Review at https://gerrit.osmocom.org/968 NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb --- M openbsc/tests/vty_test_runner.py 1 file changed, 9 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/68/968/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..9ca2c90 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1234,13 +1234,18 @@ if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): + while True: + connected = x.vty.command("show msc connection") + if connected != "MSC is connected: 0": + print "'show msc connection' says: %r" % connection + break; + conn, addr = msc.accept() if (verbose): print "MSC got connection from ", addr if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1343,4 +1348,4 @@ res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 15:44:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 15:44:18 +0000 Subject: [PATCH] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/968 to look at the new patch set (#2). NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb --- M openbsc/tests/vty_test_runner.py 1 file changed, 19 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/68/968/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..7249ed7 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1234,13 +1234,25 @@ if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + connected = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % connected + if connected != "MSC is connected: 0": + break; + + timeout_retries = 3 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + if (verbose): + print "MSC got connection from ", addr + break + except socket.timeout: + timeout_retries -= 1 + continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1343,4 +1355,4 @@ res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 16:06:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 16:06:08 +0000 Subject: [PATCH] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/968 to look at the new patch set (#3). NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb --- M openbsc/tests/vty_test_runner.py 1 file changed, 20 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/68/968/3 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..6f84d03 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1234,13 +1234,25 @@ if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + connected = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % connected + if connected != "MSC is connected: 0": + break; + + timeout_retries = 3 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + if (verbose): + print "MSC got connection from ", addr + break + except socket.timeout: + timeout_retries -= 1 + continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1340,7 +1352,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 16:19:31 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 28 Sep 2016 16:19:31 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function Message-ID: Review at https://gerrit.osmocom.org/969 DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 77 insertions(+), 61 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/1 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 4b944dc..3a9cf89 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,60 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; + + if (ft == AMR_SID) { + if (sti) { /* SID_UPDATE should be cached and send later */ + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return -EAGAIN; + } else { /* SID_FIRST got to be send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, + cmi, cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 33545c5..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -228,10 +226,7 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; + uint8_t *l1_payload, ft; int rc = 0; bool is_sid = false; @@ -266,27 +261,10 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return -EAGAIN; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return -ENOTSUP; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* force ONSET */ - marker = true; - rc = 1; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; *len = 1; if (rc != 0) { @@ -300,8 +278,8 @@ } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 908ec4c..f1a5750 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -364,27 +362,10 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return -EAGAIN; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return -ENOTSUP; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* force ONSET */ - marker = true; - rc = 1; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; *len = 1; if (rc != 0) { @@ -398,8 +379,8 @@ } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Sep 28 16:22:46 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 16:22:46 +0000 Subject: [PATCH] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/968 to look at the new patch set (#4). NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb --- M openbsc/tests/vty_test_runner.py 1 file changed, 22 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/68/968/4 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..951d45e 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1228,19 +1228,32 @@ def nat_msc_test(x, ip, port, verbose = False): msc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - msc.settimeout(32) + msc.settimeout(5) msc.bind((ip, port)) msc.listen(5) if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + connected = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % connected + if connected != "MSC is connected: 0": + break; + + timeout_retries = 1 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + if (verbose): + print "MSC got connection from ", addr + break + except socket.timeout: + print "socket timed out." + timeout_retries -= 1 + continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1340,7 +1353,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 16:22:59 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 16:22:59 +0000 Subject: [PATCH] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/968 to look at the new patch set (#5). NOT FOR MERGE: testrun for vty_test_runner.py on jenkins Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb --- M openbsc/tests/vty_test_runner.py 1 file changed, 22 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/68/968/5 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..23ae1ae 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1228,19 +1228,32 @@ def nat_msc_test(x, ip, port, verbose = False): msc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - msc.settimeout(32) + msc.settimeout(5) msc.bind((ip, port)) msc.listen(5) if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + connected = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % connected + if connected != "MSC is connected: 0": + break; + + timeout_retries = 6 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + if (verbose): + print "MSC got connection from ", addr + break + except socket.timeout: + print "socket timed out." + timeout_retries -= 1 + continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1340,7 +1353,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:52:09 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:52:09 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: fix sporadic failures: reduce timeout, r... Message-ID: Review at https://gerrit.osmocom.org/970 vty_test_runner.py: fix sporadic failures: reduce timeout, retry Upon socket timeout, retry up to six times. Reduce the timeout between retries. Raise an exception upon unexpected vty response. Print more detail to stdout. Since we would actually want as much output as we can get in a test suite, remove the 'if (verbose)' and just always print the connection source. unittest is keeping all stdout silent by default anyway. Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da --- M openbsc/tests/vty_test_runner.py 1 file changed, 22 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/70/970/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..5bb27a8 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1228,16 +1228,33 @@ def nat_msc_test(x, ip, port, verbose = False): msc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - msc.settimeout(32) + msc.settimeout(5) msc.bind((ip, port)) msc.listen(5) if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + vty_response = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % vty_response + if vty_response == "MSC is connected: 1": + # success + break; + if vty_response != "MSC is connected: 0": + raise Exception("Unexpected response to 'show msc connection'" + " vty command: %r" % vty_response) + + timeout_retries = 6 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + print "MSC got connection from ", addr + break + except socket.timeout: + print "socket timed out." + timeout_retries -= 1 + continue + if not conn: raise Exception("VTY reports MSC is connected, but I haven't" " connected yet: %r %r" % (ip, port)) -- To view, visit https://gerrit.osmocom.org/970 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:52:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:52:10 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: make unittest print all output by default Message-ID: Review at https://gerrit.osmocom.org/971 vty_test_runner.py: make unittest print all output by default Add option to TextTestRunner that shows print output on stdout. It's better to see everything in our jenkins runs and not hide test output. Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 --- M openbsc/tests/vty_test_runner.py 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/71/971/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 5bb27a8..8dc4f70 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1357,7 +1357,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) # vim: set shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/971 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:52:10 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:52:10 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: fix indents to use spaces, fix vim comment Message-ID: Review at https://gerrit.osmocom.org/972 vty_test_runner.py: fix indents to use spaces, fix vim comment Most of this file uses four spaces of indenting. Replace all tabs with spaces. Remove the erratic 'set' from the recently added vim comment at the bottom. Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf --- M openbsc/tests/vty_test_runner.py 1 file changed, 26 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/72/972/1 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 8dc4f70..a73dadd 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -65,38 +65,38 @@ return (4243, "./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp") def testForcePtime(self): - self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' rtp force-ptime 20\r') > 0) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.enable() + res = self.vty.command("show running-config") + self.assert_(res.find(' rtp force-ptime 20\r') > 0) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no rtp force-ptime") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no rtp force-ptime") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) def testOmitAudio(self): self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' sdp audio-payload send-name\r') > 0) - self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) + res = self.vty.command("show running-config") + self.assert_(res.find(' sdp audio-payload send-name\r') > 0) + self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no sdp audio-payload send-name") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) - self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no sdp audio-payload send-name") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) + self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) # TODO: test it for the trunk! def testBindAddr(self): self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("mgcp") + self.vty.command("configure terminal") + self.vty.command("mgcp") # enable.. disable bts-bind-ip self.vty.command("rtp bts-bind-ip 254.253.252.250") @@ -540,7 +540,7 @@ res = self.vty.command("write terminal") self.assert_(res.find('meas-feed scenario bla') > 0) - self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") + self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") res = self.vty.command("write terminal") self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890'), -1) self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz012345'), -1) @@ -733,7 +733,7 @@ self.assertEquals(res.find("core-location-area-code"), -1) self.assertEquals(res.find("core-cell-identity"), -1) - self.vty.command("configure terminal") + self.vty.command("configure terminal") self.vty.command("msc 0") self.vty.command("core-location-area-code 666") self.vty.command("core-cell-identity 333") @@ -1256,8 +1256,8 @@ continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1360,4 +1360,4 @@ res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/972 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:55:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:55:55 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: fix nat_msc_test(): socket attach: reduc... In-Reply-To: References: Message-ID: vty_test_runner.py: fix nat_msc_test(): socket attach: reduce timeout, retry In nat_msc_test(), upon socket timeout, retry up to six times. Reduce the timeout between retries. This should get rid of sporadic test failures that we've been seeing a lot on jenkins lately. Raise an exception upon unexpected vty response. Print more detail to stdout. Since we would actually want as much output as we can get in a test suite, remove the 'if (verbose)' and just always print the connection source. unittest is keeping all stdout silent by default anyway. Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da --- M openbsc/tests/vty_test_runner.py 1 file changed, 22 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/70/970/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..5bb27a8 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1228,16 +1228,33 @@ def nat_msc_test(x, ip, port, verbose = False): msc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - msc.settimeout(32) + msc.settimeout(5) msc.bind((ip, port)) msc.listen(5) if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + vty_response = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % vty_response + if vty_response == "MSC is connected: 1": + # success + break; + if vty_response != "MSC is connected: 0": + raise Exception("Unexpected response to 'show msc connection'" + " vty command: %r" % vty_response) + + timeout_retries = 6 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + print "MSC got connection from ", addr + break + except socket.timeout: + print "socket timed out." + timeout_retries -= 1 + continue + if not conn: raise Exception("VTY reports MSC is connected, but I haven't" " connected yet: %r %r" % (ip, port)) -- To view, visit https://gerrit.osmocom.org/970 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:55:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:55:55 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: make unittest print all output by default In-Reply-To: References: Message-ID: vty_test_runner.py: make unittest print all output by default Add option to TextTestRunner that shows print output on stdout. It's better to see everything in our jenkins runs and not hide test output. Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 --- M openbsc/tests/vty_test_runner.py 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/71/971/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 5bb27a8..8dc4f70 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1357,7 +1357,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) # vim: set shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/971 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 21:55:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 21:55:55 +0000 Subject: [PATCH] openbsc[master]: vty_test_runner.py: fix indents to use spaces, fix vim comment In-Reply-To: References: Message-ID: vty_test_runner.py: fix indents to use spaces, fix vim comment Most of this file uses four spaces of indenting. Replace all tabs with spaces. Remove the erratic 'set' from the recently added vim comment at the bottom. Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf --- M openbsc/tests/vty_test_runner.py 1 file changed, 26 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/72/972/2 diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 8dc4f70..a73dadd 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -65,38 +65,38 @@ return (4243, "./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp") def testForcePtime(self): - self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' rtp force-ptime 20\r') > 0) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.enable() + res = self.vty.command("show running-config") + self.assert_(res.find(' rtp force-ptime 20\r') > 0) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no rtp force-ptime") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no rtp force-ptime") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) def testOmitAudio(self): self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' sdp audio-payload send-name\r') > 0) - self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) + res = self.vty.command("show running-config") + self.assert_(res.find(' sdp audio-payload send-name\r') > 0) + self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no sdp audio-payload send-name") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) - self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no sdp audio-payload send-name") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) + self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) # TODO: test it for the trunk! def testBindAddr(self): self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("mgcp") + self.vty.command("configure terminal") + self.vty.command("mgcp") # enable.. disable bts-bind-ip self.vty.command("rtp bts-bind-ip 254.253.252.250") @@ -540,7 +540,7 @@ res = self.vty.command("write terminal") self.assert_(res.find('meas-feed scenario bla') > 0) - self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") + self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") res = self.vty.command("write terminal") self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890'), -1) self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz012345'), -1) @@ -733,7 +733,7 @@ self.assertEquals(res.find("core-location-area-code"), -1) self.assertEquals(res.find("core-cell-identity"), -1) - self.vty.command("configure terminal") + self.vty.command("configure terminal") self.vty.command("msc 0") self.vty.command("core-location-area-code 666") self.vty.command("core-cell-identity 333") @@ -1256,8 +1256,8 @@ continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1360,4 +1360,4 @@ res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/972 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Sep 28 23:36:01 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 23:36:01 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (14 comments) https://gerrit.osmocom.org/#/c/861/2//COMMIT_MSG Commit Message: Line 12: the specification explains that A bit within the uncompressed bitmap capital "The" , lower case "a bit"? Line 14: ignored. But current PCU implementation ignores EPDAN the sentence ends in mid-air? The problem is not explained. Line 16: fix in a subsequent commit please take care that your writing is readable, which includes ending sentences with a '.' https://gerrit.osmocom.org/#/c/861/2/src/rlc.h File src/rlc.h: Line 305: void set_v_s(int); Members m_v_s and m_v_a are not private/protected, so why add trivial setter functions? Or, alternatively, why not make them private? Is there a thought behind this? https://gerrit.osmocom.org/#/c/861/2/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2019: } a single blank line between function definitions Line 2022: * version 7.27.0 Release 7. which explains the Interpretation of the bitmap ". Which" or ", which" Line 2025: * expects the same bug. which shall be fixed in subsequent patch a lot of "which" ;) but nevermind Line 2036: uint8_t rbb[64/8]; is this 64 by chance related to RLC_EGPRS_MIN_WS, or RLC_EGPRS_WS? Line 2049: * used to simulate the EPDAN out of window scenario. During "used used". This EPDAN out of window scenario is simulated where exactly? Line 2051: * and window size of 480. same has been used below sentence punctuation, capitalisation Line 2072: dl_tbf->m_window.m_v_b.mark_unacked(1286); like in a recent patch, you're using dl_tbf->m_window and .m_v_b awfully often, which deserves a shortcut variable. Do 1286 before 1287, i.e. in sequence? Line 2091: OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286)); Do 1286 before 1287, i.e. in sequence? Line 2107: tbf_free(dl_tbf); You should clearly mark the test expectation that will be changed with the fix. Line 2127: egprs_tbf_epdan_outof_rx_window(&the_bts, 4); If this function is called only once, I'd actually insert the full test here and not spread it across two functions. OTOH, if it makes sense to test with various mcs values, then please do so and invoke the function numerous times. -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Sep 28 23:52:06 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 28 Sep 2016 23:52:06 +0000 Subject: osmo-pcu[master]: EGPRS: fix for EPDAN out of window In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (8 comments) https://gerrit.osmocom.org/#/c/862/2//COMMIT_MSG Commit Message: Line 10: according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. "The fix is made according to that section" would mean that the spec describes this patch... maybe rather "Fix alignment of EPDAN outside the RLC transmit window, according to section..." ? Line 11: The specification explains that A bit within the uncompressed bitmap If the bit is called "A", then say "that the 'A' bit", otherwise "that a bit" (same in previous commit log). Line 13: ignored Again please clearly state the problem. I kind of assume that we're failing to ignore some bit, but it should not need guess work by the reader. https://gerrit.osmocom.org/#/c/862/2/src/rlc.cpp File src/rlc.cpp: Line 108: unsigned num_blocks = rbb->cur_bit > (unsigned)distance() can distance() be negative? Casting a negative value to unsigned is inviting trouble. https://gerrit.osmocom.org/#/c/862/2/src/tbf_dl.cpp File src/tbf_dl.cpp: Line 848: unsigned num_blocks = strlen(show_rbb) > (unsigned)m_window.distance() again negative to unsigned? Line 849: ? m_window.distance() : strlen(show_rbb); don't call strlen twice. (Does the compiler optimize this? I guess not.) Line 929: unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance() unsigned distance Line 953: "V(A)..V(S) range %s\n", tbf_name(this)); Do above "this might happen..." comments need to be adjusted, or do they still reflect what is happening here? Or, maybe, does the case described in the comment need some special handling? -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 00:11:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 00:11:17 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 5: Code-Review-1 (9 comments) https://gerrit.osmocom.org/#/c/819/5//COMMIT_MSG Commit Message: Line 11: combined capacity of DL and UL for TS allocation, this would be a good place to end the sentence to make it easier to read and understand Line 12: with this there is a difference in throughput between "with this", what "this" exactly? https://gerrit.osmocom.org/#/c/819/5/src/bts.h File src/bts.h: Line 49: NO_MAXIMISE In enum values we typically use a common prefix. e.g. MAXIMISE_DIR_DL_ONLY, MAXIMISE_DIR_NONE Line 198: enum maximise_direction maximise_dir; did you check whether this struct is used only in osmo-pcu and that having an enum is fine here? The point is that enums don't have an explicitly defined size. Since all other members of this struct are very specific on the int size, I suspect an enum may break some ABI. https://gerrit.osmocom.org/#/c/819/5/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 778: if (bts->maximise_dir == DL_ONLY) { Before there was UL, DL and a third 'else', and that should have been a switch() statement. If maximise_dir has only two states now, it should be a bool and not an enum; will UL be added again at a later stage? In that case I would like a switch() statement here. https://gerrit.osmocom.org/#/c/819/5/src/pcu_vty.c File src/pcu_vty.c: Line 500: #define MAXIMISE_STR "Maximise TS allocation based on configuration\n" I still don't like "TS allocation based on configuration". Please write something that is intelligible. Line 502: DEFUN(cfg_pcu_ts_alloc_maximise_type, drop the '_type' Line 504: "maximise-direction dl", Interesting, now you've dropped the UL completely? Is UL likely to be added some time in the future? Otherwise we can just have a boolean flag called 'maximise_dl' everywhere, no need for an enum at all. Line 517: NO_STR "Maximise direction configuration\n") Once MAXIMISE_STR has a sensible string, you should use it here for 'maximise-direction', like above. -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 01:15:53 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 01:15:53 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: (26 comments) Also, still waiting for Holger to remove his -2. https://gerrit.osmocom.org/#/c/416/24/src/decoding.cpp File src/decoding.cpp: Line 700: LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exist, " 'exists'? Line 701: "CRBB LEN =%d and Starting color code =%d", 'LEN = %d' or 'LEN=%d', same with 'code=%d' https://gerrit.osmocom.org/#/c/416/24/src/egprs_rlc_compression.cpp File src/egprs_rlc_compression.cpp: Line 36: /* Function to build the codeword tree drop the 'Function to', we can see that it's a function. Furthermore, it is called 'build_codeword', so this adds no information to what is already there. Instead you should say that, something like, the function expands the given tree by incorporating the given codeword. Wait, it actually iterates the *entire list* of codewords, so you should use plurals here: build_codewords(root, cdwds) Line 43: int len; whitespace: only single spaces please Line 50: for (i = 0; i < len; i++) { single spaces Line 55: } else if (cdwd[idx][i] == '1') { it's only '0' or '1', so a simple else would suffice. (unless you want to catch odd characters in the code list, but since you're not doing that either...) Line 63: (iter->run_length) = idx; drop the braces around iter->run_length Line 65: (iter->run_length) = (idx - 63) * 64; This looks odd. The first 64 run lenghts are 0, 1, 2, ..., 63, and the following ones are 64, 128, 192, ...? Is this defined by the spec? Maybe it deserves a comment with a reference. Line 69: add a spec paragraph or table reference? Line 234: /* search_runlen function will return the runlength for the codeword We see that it is called search_runlen and that it is a function, there is no need to restate the obvious. Make the first line something like: "Calculate the run length of a code word." Line 236: * \param bmbuf[in] Recevied compressed bitmap buf "Received" Line 239: * \param rlen[out] Run length value "Calculated run length" Line 259: >>(7-(MOD8(bit_pos)))) & 0x01); add spaces after '>>' and around the '-'. No need to put (MOD8()) in braces. Line 274: /* Function to decompress crbb 'Function to' is obsolete, so is 'decompress crbb' since it merely repeats the function's name. At least write out what crbb stands for. Line 276: * \param clr_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength clr generally means 'clear', rather name it 'color_code_bit' instead. Consider using 'bool' instead of uint8_t. Is "color code" a term from the spec? From this doc alone I would not understand what to pass for this parameter, is this a technical detail everyone familiar with the spec would understand right away? Line 329: /* init function to build codeword */ obsolete comment https://gerrit.osmocom.org/#/c/416/24/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 6: In case below defines are used only in egprs_rlc_compression.c, they should be moved to that file. Line 7: #define MAX_CDWDTBL_LEN 79 /* total number of codewords */ since this is not for all thinkable codeword tables, it should have a prefix, like #define EGPRS_CODEWORDS 79 Line 8: #define BITS_TO_BYTES(X) ((X ? (X/8):0)+1) Make sure to add braces around every X. Logic error: 0 bits is 1 byte? More generally true would be (((X)? (X)/8 : 0) + ((X) & 0x7 ? 1 : 0)) Line 9: #define MOD8(X) (((X)+8) & (0x07)) mod 8 is simply '((X) & 0x7)' -- what is the +8 for?? Line 11: typedef struct node { this struct could be opaque, with only a 'typedef struct ' here, and the full definition in egprs_rlc_compression.c. Actually, for a publicly seen name, just 'Node' is too general. It should be something like 'struct egprs_compress_node'. Line 17: int decompress_crbb(int8_t compress_bmap_len, uint8_t clr_code_bit, I'd make this a static member function of class egprs_compress Line 20: /* Creating singleton class*/ whitespace: 'class */' What do you mean by "Creating"? Maybe say /* Singleton to manage the EGPRS compression algorithm. */ Line 23: public: actually, decompress_crbb could be the *only* public member of this class (and static), with all else handled privately: the ones and zeros lists, instance(), tree init. BTW, so far this supports only decompression, and compression is not needed? Line 41: if (decode_tree_init() < 0) { decode_tree_init() *always* returns zero. Just call it and make its return value void. If at some point a possible error is added in decode_tree_init(), you can abort using OSMO_ASSERT() from within decode_tree_init(). Line 48: /* Private because nobody is allow to delete on object of this type */ I'd prefer "/* singleton class, so this private destructor is left unimplemented. */" -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 01:24:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 01:24:02 +0000 Subject: openbsc[master]: vty_test_runner.py: fix nat_msc_test(): socket attach: reduc... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/970 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 29 01:24:04 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 01:24:04 +0000 Subject: [MERGED] openbsc[master]: vty_test_runner.py: fix nat_msc_test(): socket attach: reduc... In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: vty_test_runner.py: fix nat_msc_test(): socket attach: reduce timeout, retry ...................................................................... vty_test_runner.py: fix nat_msc_test(): socket attach: reduce timeout, retry In nat_msc_test(), upon socket timeout, retry up to six times. Reduce the timeout between retries. This should get rid of sporadic test failures that we've been seeing a lot on jenkins lately. Raise an exception upon unexpected vty response. Print more detail to stdout. Since we would actually want as much output as we can get in a test suite, remove the 'if (verbose)' and just always print the connection source. unittest is keeping all stdout silent by default anyway. Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da --- M openbsc/tests/vty_test_runner.py 1 file changed, 22 insertions(+), 5 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index f624fc9..5bb27a8 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1228,16 +1228,33 @@ def nat_msc_test(x, ip, port, verbose = False): msc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - msc.settimeout(32) + msc.settimeout(5) msc.bind((ip, port)) msc.listen(5) if (verbose): print "MSC is ready at " + ip conn = None - while "MSC is connected: 0" == x.vty.command("show msc connection"): - conn, addr = msc.accept() - if (verbose): - print "MSC got connection from ", addr + while True: + vty_response = x.vty.command("show msc connection") + print "'show msc connection' says: %r" % vty_response + if vty_response == "MSC is connected: 1": + # success + break; + if vty_response != "MSC is connected: 0": + raise Exception("Unexpected response to 'show msc connection'" + " vty command: %r" % vty_response) + + timeout_retries = 6 + while timeout_retries > 0: + try: + conn, addr = msc.accept() + print "MSC got connection from ", addr + break + except socket.timeout: + print "socket timed out." + timeout_retries -= 1 + continue + if not conn: raise Exception("VTY reports MSC is connected, but I haven't" " connected yet: %r %r" % (ip, port)) -- To view, visit https://gerrit.osmocom.org/970 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2f83eef55592778e54164a90e1eabeb80fb918da Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 29 08:34:42 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 08:34:42 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#2). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 76 insertions(+), 61 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/2 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 4b944dc..164ee39 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST got to be send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, + cmi, cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 33545c5..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -228,10 +226,7 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; + uint8_t *l1_payload, ft; int rc = 0; bool is_sid = false; @@ -266,27 +261,10 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return -EAGAIN; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return -ENOTSUP; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* force ONSET */ - marker = true; - rc = 1; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; *len = 1; if (rc != 0) { @@ -300,8 +278,8 @@ } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 908ec4c..f1a5750 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -364,27 +362,10 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return -EAGAIN; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return -ENOTSUP; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* force ONSET */ - marker = true; - rc = 1; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; *len = 1; if (rc != 0) { @@ -398,8 +379,8 @@ } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 08:46:52 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 08:46:52 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#3). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 95 insertions(+), 69 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/3 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 4b944dc..164ee39 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST got to be send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, + cmi, cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..08c64ab 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..3eb9bfd 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 08:52:00 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 08:52:00 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#4). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 30 insertions(+), 16 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/4 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..f78276a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -443,6 +443,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -466,14 +467,18 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { msgb_free(nmsg); nmsg = NULL; } + + if (rc > 0) /* force ONSET event */ + l1sap->u.tch.marker = 1; } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 08c64ab..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..06711e4 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,14 +460,18 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { msgb_free(nmsg); nmsg = NULL; } + + if (rc > 0) /* force ONSET event */ + l1sap->u.tch.marker = 1; } /* no message/data, we generate an empty traffic msg */ diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 3eb9bfd..f7522ba 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 09:33:33 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 09:33:33 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#5). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 64 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/5 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..9075258 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -443,6 +443,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -466,17 +467,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -504,9 +508,23 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ - l1sap->u.tch.marker = 0; - return ph_tch_req(trx, l1sap->oph.msg, l1sap); + if (rc > 0) { /* DTX: Send voice after ONSET was sent */ + rc = l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn, + false); + if (rc < 0) { + /* error while generating voice frame for L1 */ + msgb_free(nmsg); + return -BADMSG; + } + /* data request */ + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, + u8BlockNbr, + l1p->u.phDataReq.msgUnitParam.u8Size); + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); } if (msg) diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 08c64ab..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..e6dc8c1 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,17 +460,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -497,9 +501,23 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ - l1sap->u.tch.marker = 0; - return ph_tch_req(trx, l1sap->oph.msg, l1sap); + if (rc > 0) { /* DTX: Send voice after ONSET was sent */ + rc = l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn, + false); + if (rc < 0) { + /* error while generating voice frame for L1 */ + msgb_free(nmsg); + return -BADMSG; + } + /* data request */ + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, + u8BlockNbr, + l1p->u.phDataReq.msgUnitParam.u8Size); + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); } return 0; diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 3eb9bfd..f7522ba 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 09:42:05 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 09:42:05 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#4). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 96 insertions(+), 70 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/4 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 4b944dc..adff134 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST got to be send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, + cmi, cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..08c64ab 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..3eb9bfd 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 09:44:38 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 29 Sep 2016 09:44:38 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#7). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 64 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/7 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..004ce52 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -443,6 +443,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -466,17 +467,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -504,9 +508,23 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ - l1sap->u.tch.marker = 0; - return ph_tch_req(trx, l1sap->oph.msg, l1sap); + if (rc > 0) { /* DTX: Send voice after ONSET was sent */ + rc = l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn, + false); + if (rc < 0) { + /* error while generating voice frame for L1 */ + msgb_free(nmsg); + return -EBADMSG; + } + /* data request */ + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, + u8BlockNbr, + l1p->u.phDataReq.msgUnitParam.u8Size); + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); } if (msg) diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 08c64ab..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..ecb687f 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,17 +460,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -497,9 +501,23 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ - l1sap->u.tch.marker = 0; - return ph_tch_req(trx, l1sap->oph.msg, l1sap); + if (rc > 0) { /* DTX: Send voice after ONSET was sent */ + rc = l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len, u32Fn, + false); + if (rc < 0) { + /* error while generating voice frame for L1 */ + msgb_free(nmsg); + return -EBADMSG; + } + /* data request */ + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, + u8BlockNbr, + l1p->u.phDataReq.msgUnitParam.u8Size); + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); } return 0; diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 3eb9bfd..f7522ba 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 7 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 10:56:46 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 10:56:46 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 5: (1 comment) https://gerrit.osmocom.org/#/c/819/5/src/bts.h File src/bts.h: Line 198: enum maximise_direction maximise_dir; > did you check whether this struct is used only in osmo-pcu and that having Yes. This file is being used only in PCU -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:03:07 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 11:03:07 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 5: (1 comment) https://gerrit.osmocom.org/#/c/819/5/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 778: if (bts->maximise_dir == DL_ONLY) { > Before there was UL, DL and a third 'else', and that should have been a swi Yes. Intention is to provide flexibility for UL direction, When multi slots for UL is supported. so I will keep the switch statement -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:06:57 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 11:06:57 +0000 Subject: openbsc[master]: fix: send SNDCP XID only on GERAN Gb contexts In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:07:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 11:07:02 +0000 Subject: [MERGED] openbsc[master]: fix: send SNDCP XID only on GERAN Gb contexts In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: fix: send SNDCP XID only on GERAN Gb contexts ...................................................................... fix: send SNDCP XID only on GERAN Gb contexts Add a condition for GERAN Gb. SNDCP and IuPS were developed on separate branches, and the merge results in code trying to use an llme on a UTRAN Iu context where the llme is NULL, leading to stack corruption upon PDP ctx act. Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 --- M openbsc/src/gprs/sgsn_libgtp.c 1 file changed, 7 insertions(+), 5 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 127ee30..29c9f06 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -331,11 +331,13 @@ if (rc < 0) return rc; - /* Send SNDCP XID to MS */ - lle = &pctx->mm->gb.llme->lle[pctx->sapi]; - rc = sndcp_sn_xid_req(lle,pctx->nsapi); - if (rc < 0) - return rc; + if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { + /* Send SNDCP XID to MS */ + lle = &pctx->mm->gb.llme->lle[pctx->sapi]; + rc = sndcp_sn_xid_req(lle,pctx->nsapi); + if (rc < 0) + return rc; + } return 0; } -- To view, visit https://gerrit.osmocom.org/964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibb20d738c1b64d36630ce8eceb54c33ba4f1b003 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:09:15 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 11:09:15 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 5: (2 comments) https://gerrit.osmocom.org/#/c/819/5/src/pcu_vty.c File src/pcu_vty.c: Line 502: DEFUN(cfg_pcu_ts_alloc_maximise_type, > drop the '_type' Done Line 504: "maximise-direction dl", > Interesting, now you've dropped the UL completely? Yes. I am providing the flexibility to add this support for UL as well when multislot for UL is supported. so keeping this as it is. -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:11:44 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 11:11:44 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 5: (2 comments) https://gerrit.osmocom.org/#/c/819/5/src/pcu_vty.c File src/pcu_vty.c: Line 500: #define MAXIMISE_STR "Maximise TS allocation based on configuration\n" > I still don't like "TS allocation based on configuration". Done Line 517: NO_STR "Maximise direction configuration\n") > Once MAXIMISE_STR has a sensible string, you should use it here for 'maximi Done -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 5 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:27:49 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Thu, 29 Sep 2016 11:27:49 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 24: (26 comments) https://gerrit.osmocom.org/#/c/416/24/src/decoding.cpp File src/decoding.cpp: Line 700: LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exist, " > 'exists'? Done Line 701: "CRBB LEN =%d and Starting color code =%d", > 'LEN = %d' or 'LEN=%d', same with 'code=%d' Done https://gerrit.osmocom.org/#/c/416/24/src/egprs_rlc_compression.cpp File src/egprs_rlc_compression.cpp: Line 36: /* Function to build the codeword tree > drop the 'Function to', we can see that it's a function. Furthermore, it is Done Line 43: int len; > whitespace: only single spaces please Done Line 50: for (i = 0; i < len; i++) { > single spaces Done Line 55: } else if (cdwd[idx][i] == '1') { > it's only '0' or '1', so a simple else would suffice. Done Line 63: (iter->run_length) = idx; > drop the braces around iter->run_length Done Line 65: (iter->run_length) = (idx - 63) * 64; > This looks odd. The first 64 run lenghts are 0, 1, 2, ..., 63, and the foll Done Line 69: > add a spec paragraph or table reference? Done Line 234: /* search_runlen function will return the runlength for the codeword > We see that it is called search_runlen and that it is a function, there is Done Line 236: * \param bmbuf[in] Recevied compressed bitmap buf > "Received" Done Line 239: * \param rlen[out] Run length value > "Calculated run length" Done Line 259: >>(7-(MOD8(bit_pos)))) & 0x01); > add spaces after '>>' and around the '-'. No need to put (MOD8()) in braces Done Line 274: /* Function to decompress crbb > 'Function to' is obsolete, so is 'decompress crbb' since it merely repeats Done Line 276: * \param clr_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength > clr generally means 'clear', rather name it 'color_code_bit' instead. Consi Done Line 329: /* init function to build codeword */ > obsolete comment Done https://gerrit.osmocom.org/#/c/416/24/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 6: > In case below defines are used only in egprs_rlc_compression.c, they should Done Line 7: #define MAX_CDWDTBL_LEN 79 /* total number of codewords */ > since this is not for all thinkable codeword tables, it should have a prefi Done Line 8: #define BITS_TO_BYTES(X) ((X ? (X/8):0)+1) > Make sure to add braces around every X. Here we are passing position of the bit to the macro and expecting the byte number. For example if the bit position is between 0-7 then it should return 1. If the bit position is between 8-15 it should return 2 and so on. Line 9: #define MOD8(X) (((X)+8) & (0x07)) > mod 8 is simply '((X) & 0x7)' -- what is the +8 for?? Done Line 11: typedef struct node { > this struct could be opaque, with only a 'typedef struct ' here, and I will change the structure instance name as you suggested. In normally all structures in osmo-pcu files are defined in .h file itself eg:gsm_rlcmac.h. Line 17: int decompress_crbb(int8_t compress_bmap_len, uint8_t clr_code_bit, > I'd make this a static member function of class egprs_compress Done Line 20: /* Creating singleton class*/ > whitespace: 'class */' Done Line 23: public: > actually, decompress_crbb could be the *only* public member of this class ( Compression support will be added in next patch. Line 41: if (decode_tree_init() < 0) { > decode_tree_init() *always* returns zero. Done Line 48: /* Private because nobody is allow to delete on object of this type */ > I'd prefer Done -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 24 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:38:48 2016 From: gerrit-no-reply at lists.osmocom.org (pravin) Date: Thu, 29 Sep 2016 11:38:48 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Hello Max, Neels Hofmeyr, arvind.sirsikar, Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/416 to look at the new patch set (#25). EGPRS: Add EPDAN CRBB Tree based decoding Implemented tree based algorithm to decode compressed bitmap in EPDAN as described in section 9.1.10 of 3GPP 44.060. This algorithm intends to improve the performance over existing method. New Regression test is added under bitcomp directory. Test case is added to validate decompressed result of the bitmap Present in EPDAN. Test is done for multiple bitmaps of varying length. Invalid inputs are also part of the test vector. Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce --- M src/Makefile.am M src/decoding.cpp A src/egprs_rlc_compression.cpp A src/egprs_rlc_compression.h M tests/Makefile.am A tests/bitcomp/BitcompTest.cpp A tests/bitcomp/BitcompTest.err A tests/bitcomp/BitcompTest.ok M tests/testsuite.at 9 files changed, 788 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/16/416/25 diff --git a/src/Makefile.am b/src/Makefile.am index 9bdec2f..9b047e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,7 +62,8 @@ rlc.cpp \ osmobts_sock.cpp \ gprs_codel.c \ - gprs_coding_scheme.cpp + gprs_coding_scheme.cpp \ + egprs_rlc_compression.cpp bin_PROGRAMS = \ osmo-pcu @@ -94,7 +95,8 @@ pcu_utils.h \ cxx_linuxlist.h \ gprs_codel.h \ - gprs_coding_scheme.h + gprs_coding_scheme.h \ + egprs_rlc_compression.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/decoding.cpp b/src/decoding.cpp index 3f5c4d2..6ae4b16 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -20,6 +20,7 @@ #include #include #include +#include extern "C" { #include @@ -692,21 +693,17 @@ if (crbb_len > 0) { int old_len = bits->cur_bit; - struct bitvec crbb; - crbb.data = (uint8_t *)desc->CRBB; - crbb.data_len = sizeof(desc->CRBB); - crbb.cur_bit = desc->CRBB_LENGTH; - - rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE, - bits); - + LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exists, " + "CRBB LEN = %d and Starting color code = %d", + desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE); + rc = egprs_compress::decompress_crbb(desc->CRBB_LENGTH, + desc->CRBB_STARTING_COLOR_CODE, desc->CRBB, bits); if (rc < 0) { LOGP(DRLCMACUL, LOGL_NOTICE, - "Failed to decode CRBB: " - "length %d, data '%s'\n", - desc->CRBB_LENGTH, - osmo_hexdump(crbb.data, crbb.data_len)); + "Failed to decode CRBB: length %d, data '%s'\n", + desc->CRBB_LENGTH, osmo_hexdump( + desc->CRBB, (desc->CRBB_LENGTH + 7)/8)); /* We don't know the SSN offset for the URBB, * return what we have so far and assume the * bitmap has stopped here */ diff --git a/src/egprs_rlc_compression.cpp b/src/egprs_rlc_compression.cpp new file mode 100644 index 0000000..c1baaa9 --- /dev/null +++ b/src/egprs_rlc_compression.cpp @@ -0,0 +1,344 @@ +/* egprs_rlc_compression.h +* Routines for EGPRS RLC bitmap compression handling +*/ +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +#define EGPRS_CODEWORDS 79 /* total number of codewords */ + +extern void *tall_pcu_ctx; +extern const char *one_run_len_code_list[EGPRS_CODEWORDS]; +extern const char *zero_run_len_code_list[EGPRS_CODEWORDS]; + +egprs_compress *egprs_compress::s_instance = 0; + +egprs_compress_node *egprs_compress::create_tree_node(void *parent) +{ + egprs_compress_node *new_node; + + new_node = talloc_zero(parent, egprs_compress_node); + new_node->left = NULL; + new_node->right = NULL; + new_node->run_length = -1; + return new_node; +} + +/* The function expands the given tree by incorporating + * the given codewords. + * \param root[in] Root of Ones or Zeros tree + * \param cdwd[in] Code word + */ +void egprs_compress::build_codewords(egprs_compress_node *root, const char *cdwd[]) +{ + egprs_compress_node *iter; + int len; + int i; + int idx; + + for (idx = 0; idx < EGPRS_CODEWORDS; idx++) { + len = strlen((const char *)cdwd[idx]); + iter = root; + for (i = 0; i < len; i++) { + if (cdwd[idx][i] == '0') { + if (!iter->left) + iter->left = create_tree_node(root); + iter = iter->left; + } else { + if (!iter->right) + iter->right = create_tree_node(root); + iter = iter->right; + } + } + if (iter) { + if (idx < 64) + iter->run_length = idx; + else + /* The first 64 run lengths are 0, 1, 2, ..., 63 + * and the following ones are 64, 128, 192 described in + * section 9.1.10 of 3gpp 44.060 */ + iter->run_length = (idx - 63) * 64; + } + } +} + +/* The code words for one run length and zero + * run length are described in table 9.1.10.1 + * of 3gpp 44.060 + */ +const char *one_run_len_code_list[EGPRS_CODEWORDS] = { + "00110101", + "000111", + "0111", + "1000", + "1011", + "1100", + "1110", + "1111", + "10011", + "10100", + "00111", + "01000", + "001000", + "000011", + "110100", + "110101", + "101010", + "101011", + "0100111", + "0001100", + "0001000", + "0010111", + "0000011", + "0000100", + "0101000", + "0101011", + "0010011", + "0100100", + "0011000", + "00000010", + "00000011", + "00011010", + "00011011", + "00010010", + "00010011", + "00010100", + "00010101", + "00010110", + "00010111", + "00101000", + "00101001", + "00101010", + "00101011", + "00101100", + "00101101", + "00000100", + "00000101", + "00001010", + "00001011", + "01010010", + "01010011", + "01010100", + "01010101", + "00100100", + "00100101", + "01011000", + "01011001", + "01011010", + "01011011", + "01001010", + "01001011", + "00110010", + "00110011", + "00110100", + "11011", + "10010", + "010111", + "0110111", + "00110110", + "00110111", + "01100100", + "01100101", + "01101000", + "01100111", + "011001100", + "011001101", + "011010010", + "011010011", + "011010100" +}; + +const char *zero_run_len_code_list[EGPRS_CODEWORDS] = { + "0000110111", + "10", + "11", + "010", + "011", + "0011", + "0010", + "00011", + "000101", + "000100", + "0000100", + "0000101", + "0000111", + "00000100", + "00000111", + "000011000", + "0000010111", + "0000011000", + "0000001000", + "00001100111", + "00001101000", + "00001101100", + "00000110111", + "00000101000", + "00000010111", + "00000011000", + "000011001010", + "000011001011", + "000011001100", + "000011001101", + "000001101000", + "000001101001", + "000001101010", + "000001101011", + "000011010010", + "000011010011", + "000011010100", + "000011010101", + "000011010110", + "000011010111", + "000001101100", + "000001101101", + "000011011010", + "000011011011", + "000001010100", + "000001010101", + "000001010110", + "000001010111", + "000001100100", + "000001100101", + "000001010010", + "000001010011", + "000000100100", + "000000110111", + "000000111000", + "000000100111", + "000000101000", + "000001011000", + "000001011001", + "000000101011", + "000000101100", + "000001011010", + "000001100110", + "000001100111", + "0000001111", + "000011001000", + "000011001001", + "000001011011", + "000000110011", + "000000110100", + "000000110101", + "0000001101100", + "0000001101101", + "0000001001010", + "0000001001011", + "0000001001100", + "0000001001101", + "0000001110010", + "0000001110011" +}; + +/* Calculate runlength of a codeword + * \param root[in] Root of Ones or Zeros tree + * \param bmbuf[in] Received compressed bitmap buf + * \param bit_pos[in] The start bit pos to read codeword + * \param len_codewd[in] Length of code word + * \param rlen[out] Caluculate run length + */ +static int search_runlen( + egprs_compress_node *root, + const uint8_t *bmbuf, + uint8_t bit_pos, + uint8_t *len_codewd, + uint16_t *rlen) +{ + egprs_compress_node *iter; + uint8_t dir; + + iter = root; + *len_codewd = 0; + + while (iter->run_length == -1) { + if ((!iter->left) && (!iter->right)) + return -1; + /* get the bit value at the bitpos and put it in right most of dir */ + dir = ((bmbuf[BITS_TO_BYTES(bit_pos) - 1] + >> (7 - MOD8(bit_pos))) & 0x01); + (bit_pos)++; + (*len_codewd)++; + if (((dir&0x01) == 0) && (iter->left != NULL)) + iter = iter->left; + else if (((dir&0x01) == 1) && (iter->right != NULL)) + iter = iter->right; + else + return -1; + } + LOGP(DRLCMACUL, LOGL_DEBUG, "Run_length = %d\n", iter->run_length); + (*rlen) = (iter->run_length); + return 1; +} + +/* Function to decompress compressed received block bitmap + * \param compress_bmap_len[in] Compressed bitmap length + * \param color_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength + * \param orig_crbb_buf[in] Received block crbb bitmap + * \param dest[out] Uncompressed bitvector + */ +int egprs_compress::decompress_crbb( + int8_t compress_bmap_len, + bool color_code_bit, + const uint8_t *orig_crbb_buf, + bitvec *dest) +{ + + uint8_t bit_pos = 0; + uint8_t data = 0x0; + egprs_compress_node *list = NULL; + uint8_t nbits = 0; /* number of bits of codeword */ + uint16_t run_length = 0; + uint16_t cbmaplen = 0; /* compressed bitmap part after decompression */ + unsigned wp = dest->cur_bit; + int rc = 0; + egprs_compress *compress = egprs_compress::instance(); + + while (compress_bmap_len > 0) { + if (color_code_bit == 1) { + data = 0xff; + list = compress->ones_list; + } else { + data = 0x00; + list = compress->zeros_list; + } + rc = search_runlen(list, orig_crbb_buf, + bit_pos, &nbits, &run_length); + if (rc == -1) + return -1; + /* If run length > 64, need makeup and terminating code */ + if (run_length < 64) + color_code_bit ? color_code_bit = 0 : color_code_bit = 1; + cbmaplen = cbmaplen + run_length; + /* put run length of Ones in uncompressed bitmap */ + while (run_length != 0) { + if (run_length > 8) { + bitvec_write_field(dest, wp, data, 8); + run_length = run_length - 8; + } else { + bitvec_write_field(dest, wp, data, run_length); + run_length = 0; + } + } + bit_pos = bit_pos + nbits; + compress_bmap_len = compress_bmap_len - nbits; + } + return 0; +} + +void egprs_compress::decode_tree_init() +{ + ones_list = create_tree_node(tall_pcu_ctx); + zeros_list = create_tree_node(tall_pcu_ctx); + build_codewords(ones_list, one_run_len_code_list); + build_codewords(zeros_list, zero_run_len_code_list); +} diff --git a/src/egprs_rlc_compression.h b/src/egprs_rlc_compression.h new file mode 100644 index 0000000..4b6646e --- /dev/null +++ b/src/egprs_rlc_compression.h @@ -0,0 +1,47 @@ +/* egprs_rlc_compression.h + * Routines for EGPRS RLC bitmap compression handling + */ + +#pragma once + +#define BITS_TO_BYTES(X) (((X) ? (X)/8 : 0) + 1) +#define MOD8(X) ((X) & (0x07)) + +typedef struct egprs_compress_node{ + struct egprs_compress_node *left; + struct egprs_compress_node *right; + int run_length; +} egprs_compress_node; + +/* Singleton to manage the EGPRS compression algorithm. */ +class egprs_compress +{ +public: + static int decompress_crbb(int8_t compress_bmap_len, + bool color_code_bit, const uint8_t *orig_buf, + bitvec *dest); + +private: + static egprs_compress *s_instance; + egprs_compress_node *ones_list; + egprs_compress_node *zeros_list; + + void decode_tree_init(void); + + static egprs_compress *instance() + { + if (!s_instance) + s_instance = new egprs_compress; + + return s_instance; + } + + egprs_compress() + { + decode_tree_init(); + } + egprs_compress_node *create_tree_node(void *); + void build_codewords(egprs_compress_node *root, const char *cdwd[]); + /* singleton class, so this private destructor is left unimplemented. */ + ~egprs_compress(); +}; diff --git a/tests/Makefile.am b/tests/Makefile.am index 2a3415e..a24f4ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/ AM_LDFLAGS = -lrt -check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest +check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest llc/LlcTest codel/codel_test edge/EdgeTest bitcomp/BitcompTest noinst_PROGRAMS = emu/pcu_emu rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp @@ -23,6 +23,11 @@ $(top_builddir)/src/libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCORE_LIBS) \ + $(COMMON_LA) + +bitcomp_BitcompTest_SOURCES = bitcomp/BitcompTest.cpp ../src/egprs_rlc_compression.cpp +bitcomp_BitcompTest_LDADD = \ $(LIBOSMOCORE_LIBS) \ $(COMMON_LA) @@ -108,6 +113,7 @@ rlcmac/RLCMACTest.ok rlcmac/RLCMACTest.err \ alloc/AllocTest.ok alloc/AllocTest.err \ tbf/TbfTest.ok tbf/TbfTest.err \ + bitcomp/BitcompTest.ok bitcomp/BitcompTest.err \ types/TypesTest.ok types/TypesTest.err \ ms/MsTest.ok ms/MsTest.err \ llc/LlcTest.ok llc/LlcTest.err \ diff --git a/tests/bitcomp/BitcompTest.cpp b/tests/bitcomp/BitcompTest.cpp new file mode 100644 index 0000000..fd3b0df --- /dev/null +++ b/tests/bitcomp/BitcompTest.cpp @@ -0,0 +1,236 @@ +#include +#include + +#include "rlc.h" +#include "gprs_debug.h" +#include +#include "egprs_rlc_compression.h" + +extern "C" { +#include +#include +#include +#include +} + +#define NEW 1 +#define MASK(n) (0xFF << (8-n)) +#define MAX_CRBB_LEN 23 +#define MAX_URBB_LEN 40 + +void *tall_pcu_ctx; + +struct test_data { + int8_t crbb_len; + uint8_t cc; + uint8_t crbb_data[MAX_CRBB_LEN]; /* compressed data */ + uint8_t ucmp_data[MAX_URBB_LEN]; /* uncompressed data */ + int ucmp_len; + int verify; +} test[] = { + { .crbb_len = 67, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xdb + }, + .ucmp_len = 194, .verify = 1 + }, + { .crbb_len = 40, .cc = 1, + .crbb_data = { + 0x53, 0x06, 0xc5, 0x40, 0x6d + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x03 + }, + .ucmp_len = 182, .verify = 1 + }, + { .crbb_len = 8, .cc = 1, + .crbb_data = {0x02}, + .ucmp_data = {0xff, 0xff, 0xff, 0xf8}, + .ucmp_len = 29, .verify = 1 + }, + { .crbb_len = 103, .cc = 1, + .crbb_data = { + 0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03, + 0x71, 0xb0, 0x6e, 0x24 + }, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff + }, + .ucmp_len = 288, .verify = 1 + }, + /* Test vector from libosmocore test */ + { .crbb_len = 35, .cc = 0, + .crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80}, + .ucmp_data = {0x37, 0x47, 0x81, 0xf0}, + .ucmp_len = 28, .verify = 1 + }, + { .crbb_len = 18, .cc = 1, + .crbb_data = {0xdd, 0x41, 0x00}, + .ucmp_data = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00 + }, + .ucmp_len = 90, .verify = 1 + }, + /*Invalid inputs*/ + { .crbb_len = 18, .cc = 1, + .crbb_data = {0x1E, 0x70, 0xc0}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 14, .cc = 1, + .crbb_data = {0x00, 0x1E, 0x7c}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + }, + { .crbb_len = 24, .cc = 0, + .crbb_data = {0x00, 0x00, 0x00}, + .ucmp_data = {0x0}, + .ucmp_len = 0, .verify = 0 + } + }; + +static const struct log_info_cat default_categories[] = { + {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, + {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, + {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1}, + {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1}, + {"DNS", "\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO, 1}, + {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO, 1}, + {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1}, +}; + +static int filter_fn(const struct log_context *ctx, + struct log_target *tar) +{ + return 1; +} + +/* To verify the result with expected result */ +int check_result(bitvec bits, uint8_t *exp_data, int exp_len) +{ + if (bits.cur_bit != exp_len) + return 0; + size_t n = (exp_len / 8); + int rem = (exp_len % 8); + + if (memcmp(exp_data, bits.data, n) == 0) { + if (rem == 0) + return 1; + if ((bits.data[n] & MASK(rem)) == ((*(exp_data + n)) & MASK(rem))) + return 1; + else + return 0; + } else + return 0; +} + +/* To test decoding of compressed bitmap by Tree based method + * and to verify the result with expected result + * for invalid input verfication is suppressed + */ +static void test_EPDAN_decode_tree(void) +{ + bitvec dest; + int init_flag = 1; + int itr; + int rc; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + + printf("=== start %s ===\n", __func__); + + for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) { + dest.data = bits_data; + dest.data_len = sizeof(bits_data); + dest.cur_bit = 0; + memset(dest.data, 0, sizeof(bits_data)); + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTest:%d\nTree based decoding:" + "\nuncompressed data = %s\nlen = %d\n", itr + 1, + osmo_hexdump(test[itr].crbb_data, + (test[itr].crbb_len + 7)/8), test[itr].crbb_len + ); + rc = egprs_compress::decompress_crbb(test[itr].crbb_len, + test[itr].cc, test[itr].crbb_data, &dest); + if (rc < 0) { + LOGP(DRLCMACUL, LOGL_NOTICE, + "\nFailed to decode CRBB: length %d, data %s", + test[itr].crbb_len, osmo_hexdump( + test[itr].crbb_data, (test[itr].crbb_len + 7)/8)); + } + if (init_flag) + init_flag = 0; + if (test[itr].verify) { + if (check_result(dest, test[itr].ucmp_data, + test[itr].ucmp_len) == 0) { + LOGP(DRLCMACDL, LOGL_DEBUG, "\nTree based decoding" + ":Error\nexpected data = %s\nexpected" + " len = %d\ndecoded data = %s\n" + "decoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + OSMO_ASSERT(0); + } + } + LOGP(DRLCMACDL, LOGL_DEBUG, "\nexpected data = %s\nexpected len = %d" + "\ndecoded data = %s\ndecoded len = %d\n", + osmo_hexdump(test[itr].ucmp_data, + (test[itr].ucmp_len + 7)/8), + test[itr].ucmp_len, osmo_hexdump(dest.data, + (dest.cur_bit + 7)/8), dest.cur_bit + ); + } + + printf("=== end %s ===\n", __func__); +} + +const struct log_info debug_log_info = { + filter_fn, + (struct log_info_cat *)default_categories, + ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + osmo_init_logging(&debug_log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + + tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context"); + if (!tall_pcu_ctx) + abort(); + + test_EPDAN_decode_tree(); + + if (getenv("TALLOC_REPORT_FULL")) + talloc_report_full(tall_pcu_ctx, stderr); + talloc_free(tall_pcu_ctx); + return EXIT_SUCCESS; +} + +/* + * stubs that should not be reached + */ +extern "C" { +void l1if_pdch_req() { abort(); } +void l1if_connect_pdch() { abort(); } +void l1if_close_pdch() { abort(); } +void l1if_open_pdch() { abort(); } +} + diff --git a/tests/bitcomp/BitcompTest.err b/tests/bitcomp/BitcompTest.err new file mode 100644 index 0000000..7481d72 --- /dev/null +++ b/tests/bitcomp/BitcompTest.err @@ -0,0 +1,132 @@ + +Test:1 +Tree based decoding: +uncompressed data = 02 0c a0 30 cb 1a 0c e3 6c +len = 67 +Run_length = 29 +Run_length = 26 +Run_length = 30 +Run_length = 27 +Run_length = 31 +Run_length = 19 +Run_length = 32 + +expected data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +expected len = 194 +decoded data = ff ff ff f8 00 00 01 ff ff ff f8 00 00 00 ff ff ff fe 00 00 3f ff ff ff db +decoded len = 194 + +Test:2 +Tree based decoding: +uncompressed data = 53 06 c5 40 6d +len = 40 +Run_length = 50 +Run_length = 40 +Run_length = 51 +Run_length = 41 + +expected data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +expected len = 182 +decoded data = ff ff ff ff ff ff c0 00 00 00 00 3f ff ff ff ff ff f8 00 00 00 00 03 +decoded len = 182 + +Test:3 +Tree based decoding: +uncompressed data = 02 +len = 8 +Run_length = 29 + +expected data = ff ff ff f8 +expected len = 29 +decoded data = ff ff ff f8 +decoded len = 29 + +Test:4 +Tree based decoding: +uncompressed data = 02 0c e0 41 a0 0c 36 0d 03 71 b0 6e 24 +len = 103 +Run_length = 29 +Run_length = 19 +Run_length = 29 +Run_length = 20 +Run_length = 30 +Run_length = 21 +Run_length = 31 +Run_length = 22 +Run_length = 32 +Run_length = 22 +Run_length = 33 + +expected data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +expected len = 288 +decoded data = ff ff ff f8 00 00 ff ff ff f8 00 00 7f ff ff fe 00 00 0f ff ff ff e0 00 00 7f ff ff ff 80 00 01 ff ff ff ff +decoded len = 288 + +Test:5 +Tree based decoding: +uncompressed data = de 88 75 65 80 +len = 35 +Run_length = 2 +Run_length = 2 +Run_length = 1 +Run_length = 3 +Run_length = 1 +Run_length = 1 +Run_length = 3 +Run_length = 4 +Run_length = 6 +Run_length = 5 + +expected data = 37 47 81 f0 +expected len = 28 +decoded data = 37 47 81 f0 +decoded len = 28 + +Test:6 +Tree based decoding: +uncompressed data = dd 41 00 +len = 18 +Run_length = 64 +Run_length = 16 +Run_length = 10 + +expected data = ff ff ff ff ff ff ff ff ff ff 00 00 +expected len = 90 +decoded data = ff ff ff ff ff ff ff ff ff ff 00 00 +decoded len = 90 + +Test:7 +Tree based decoding: +uncompressed data = 1e 70 c0 +len = 18 +Run_length = 1 +Run_length = 1 +Run_length = 2 +Run_length = 15 + +expected data = +expected len = 0 +decoded data = +decoded len = 19 + +Test:8 +Tree based decoding: +uncompressed data = 00 1e +len = 14 + +Failed to decode CRBB: length 14, data 00 1e +expected data = +expected len = 0 +decoded data = +decoded len = 0 + +Test:9 +Tree based decoding: +uncompressed data = 00 00 00 +len = 24 + +Failed to decode CRBB: length 24, data 00 00 00 +expected data = +expected len = 0 +decoded data = +decoded len = 0 diff --git a/tests/bitcomp/BitcompTest.ok b/tests/bitcomp/BitcompTest.ok new file mode 100644 index 0000000..f7720fc --- /dev/null +++ b/tests/bitcomp/BitcompTest.ok @@ -0,0 +1,2 @@ +=== start test_EPDAN_decode_tree === +=== end test_EPDAN_decode_tree === diff --git a/tests/testsuite.at b/tests/testsuite.at index 1049b31..e42a0fd 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -23,6 +23,13 @@ AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/tbf/TbfTest], [0], [expout], [experr]) AT_CLEANUP +AT_SETUP([bitcomp]) +AT_KEYWORDS([bitcomp]) +cat $abs_srcdir/bitcomp/BitcompTest.ok > expout +cat $abs_srcdir/bitcomp/BitcompTest.err > experr +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/bitcomp/BitcompTest], [0], [expout], [experr]) +AT_CLEANUP + AT_SETUP([edge]) AT_KEYWORDS([edge]) cat $abs_srcdir/edge/EdgeTest.ok > expout -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 25 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:56:11 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 11:56:11 +0000 Subject: [PATCH] osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/819 to look at the new patch set (#6). Fix: DL slot allocation based on direction configured Currently number of TS for second DL TBF is less compared to first DL TBF because PCU is considering the combined capacity of DL and UL for TS allocation. Since 2nd DL TBF has less DL slot compared to 2nd TBF, There is a difference in throughput between the 2 DL TBFs. This patch enables the user to maximize the number of DL TSs for the TBF based on the direction configured through VTY with cfg_pcu_ts_alloc_maximise_cmd Related: OS#1792 Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 --- M src/bts.h M src/gprs_rlcmac_ts_alloc.cpp M src/pcu_main.cpp M src/pcu_vty.c M tests/alloc/AllocTest.cpp M tests/alloc/AllocTest.ok 6 files changed, 55 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/819/6 diff --git a/src/bts.h b/src/bts.h index ba6fc4d..7b3bbd4 100644 --- a/src/bts.h +++ b/src/bts.h @@ -44,6 +44,10 @@ #define LLC_CODEL_USE_DEFAULT (-1) #define MAX_GPRS_CS 9 +enum maximise_direction { + MAXIMISE_DIR_DL_ONLY, + MAXIMISE_DIR_NONE +}; struct BTS; struct GprsMs; @@ -191,6 +195,8 @@ /* 0 to support resegmentation in DL, 1 for no reseg */ uint8_t dl_arq_type; + enum maximise_direction maximise_dir; + uint32_t ms_idle_sec; uint8_t cs_adj_enabled; uint8_t cs_adj_upper_limit; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 57197b2..5e2bb0d 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -775,9 +775,16 @@ rx_window & tx_window, 'C'), capacity); #endif - - if (capacity <= max_capacity) - continue; + switch (bts->maximise_dir) { + case MAXIMISE_DIR_DL_ONLY: + if (rx_window < max_dl_slots) + continue; + break; + default: + if (capacity <= max_capacity) + continue; + break; + } max_capacity = capacity; max_ul_slots = tx_window; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 4a75c79..57bccd1 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -217,6 +217,8 @@ */ bts->dl_arq_type = EGPRS_ARQ1; + bts->maximise_dir = MAXIMISE_DIR_NONE; + msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 535d512..6e7d0fe 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -497,6 +497,32 @@ return CMD_SUCCESS; } +#define MAXIMISE_STR "Maximise direction based on configuration\n" + +DEFUN(cfg_pcu_ts_alloc_maximise, + cfg_pcu_ts_alloc_maximise_cmd, + "maximise-direction dl", + MAXIMISE_STR "Maximise DL capacity\n") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->maximise_dir = MAXIMISE_DIR_DL_ONLY; + + return CMD_SUCCESS; +} + +DEFUN(cfg_pcu_no_maximise_direction, + cfg_pcu_no_maximise_direction_cmd, + "no maximise-direction", + NO_STR MAXIMISE_STR) +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->maximise_dir = MAXIMISE_DIR_NONE; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_window_size, cfg_pcu_window_size_cmd, "window-size <0-1024> [<0-256>]", @@ -972,6 +998,8 @@ install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd); + install_element(PCU_NODE, &cfg_pcu_ts_alloc_maximise_cmd); + install_element(PCU_NODE, &cfg_pcu_no_maximise_direction_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index f7794f7..39033a6 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -118,6 +118,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; + bts->maximise_dir = MAXIMISE_DIR_NONE; struct gprs_rlcmac_trx *trx = &bts->trx[0]; for (i = 0; i < 8; i += 1) @@ -196,6 +197,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = MAXIMISE_DIR_NONE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -238,6 +240,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = MAXIMISE_DIR_NONE; trx = &bts->trx[0]; trx->pdch[5].enable(); @@ -285,6 +288,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = MAXIMISE_DIR_NONE; trx = &bts->trx[0]; trx->pdch[1].enable(); @@ -660,6 +664,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = MAXIMISE_DIR_NONE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -698,6 +703,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = algo; + bts->maximise_dir = MAXIMISE_DIR_NONE; trx = &bts->trx[0]; trx->pdch[3].enable(); @@ -806,6 +812,7 @@ bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_b; + bts->maximise_dir = MAXIMISE_DIR_DL_ONLY; trx = &bts->trx[0]; trx->pdch[4].enable(); @@ -830,13 +837,8 @@ if (dl_tbf2->pdch[i]) numTs2++; } - - /* - * TODO: currently 2nd DL TBF gets 3 TS - * This behaviour will be fixed in subsequent patch - */ printf("TBF2: numTs(%d)\n", numTs2); - OSMO_ASSERT(numTs2 == 3); + OSMO_ASSERT(numTs2 == 4); tbf_free(dl_tbf1); tbf_free(dl_tbf2); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index cbb65aa..9717411 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -10795,4 +10795,4 @@ Successfully allocated 160 TBFs Testing DL TS allocation for Multi UEs TBF1: numTs(4) -TBF2: numTs(3) +TBF2: numTs(4) -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 29 11:59:16 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 11:59:16 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 6: (7 comments) https://gerrit.osmocom.org/#/c/819/5//COMMIT_MSG Commit Message: Line 11: combined capacity of DL and UL for TS allocation. > this would be a good place to end the sentence to make it easier to read an Done Line 12: Since 2nd DL TBF has less DL slot compared to 2nd TBF, > "with this", what "this" exactly? Done https://gerrit.osmocom.org/#/c/819/5/src/bts.h File src/bts.h: Line 49: MAXIMISE_DIR_NONE > In enum values we typically use a common prefix. Done Line 198: enum maximise_direction maximise_dir; > Yes. This file is being used only in PCU Done https://gerrit.osmocom.org/#/c/819/5/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 778: switch (bts->maximise_dir) { > Yes. Intention is to provide flexibility for UL direction, When multi slots Done https://gerrit.osmocom.org/#/c/819/5/src/pcu_vty.c File src/pcu_vty.c: Line 504: "maximise-direction dl", > Yes. I am providing the flexibility to add this support for UL as well when Done Line 517: NO_STR MAXIMISE_STR) > Done Done -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 12:36:03 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 29 Sep 2016 12:36:03 +0000 Subject: [ABANDON] osmo-bts[master]: octphy: Dont't crash if transceiver is re-initalized In-Reply-To: References: Message-ID: dexter has abandoned this change. Change subject: octphy: Dont't crash if transceiver is re-initalized ...................................................................... Abandoned Discussed with octasic -- To view, visit https://gerrit.osmocom.org/907 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I3fccc8e45843d255b256a753547436c39bbf38b0 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 12:37:07 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 29 Sep 2016 12:37:07 +0000 Subject: [ABANDON] osmo-bts[master]: common: Improvements for channel measurement reporting In-Reply-To: References: Message-ID: dexter has abandoned this change. Change subject: common: Improvements for channel measurement reporting ...................................................................... Abandoned discussed with octasic -- To view, visit https://gerrit.osmocom.org/901 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Id362c52ff5482732a6ee5ce2d9c813f2b66201f9 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Sep 29 12:42:10 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 12:42:10 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/861/2/src/rlc.h File src/rlc.h: Line 305: void set_v_s(int); > Members m_v_s and m_v_a are not private/protected, so why add trivial sette Done -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 13:43:04 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 13:43:04 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Patch Set 2: (4 comments) https://gerrit.osmocom.org/#/c/861/2/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2019: } > a single blank line between function definitions Done Line 2022: * version 7.27.0 Release 7. which explains the Interpretation of the bitmap > ". Which" or ", which" Done Line 2036: uint8_t rbb[64/8]; > is this 64 by chance related to RLC_EGPRS_MIN_WS, or RLC_EGPRS_WS? not related to this test case. removing. Line 2049: * used to simulate the EPDAN out of window scenario. During > "used used". Done -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Sep 29 13:54:36 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Thu, 29 Sep 2016 13:54:36 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/861 to look at the new patch set (#3). EGPRS: add test case to show EPDAN BSN out of window bug This patch adds a test case test_egprs_tbf_epdan_out_of_rx_window, Which expects a current bug with EPDAN for Interpretation of the bitmap explained in section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that a bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored. But current PCU implementation drops the EPDAN and does not update status of the BSN which are inside the window. The test's expectation is corrected along with the bug fix in a subsequent commit Related: OS#1789 Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 --- M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 3 files changed, 147 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/61/861/3 diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3e17d8f..3ae9cbe 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -26,6 +26,7 @@ #include "pcu_utils.h" #include "gprs_bssgp_pcu.h" #include "pcu_l1_if.h" +#include "decoding.h" extern "C" { #include "pcu_vty.h" @@ -2017,6 +2018,113 @@ printf("=== end %s ===\n", __func__); } +/* + * This test simulates the section 9.1.8.2.4 of 44.060 + * version 7.27.0 Release 7. Which explains the Interpretation of the bitmap + * as a bit within the uncompressed bitmap whose BSN is not within the transmit + * window shall be ignored. Which fails because of existing bug. This test case + * expects the same bug. which shall be fixed in subsequent patch + */ +static void test_egprs_tbf_epdan_out_of_rx_window(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + int i; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + uint32_t fn = 2654167; /* 17,25,9 */ + uint8_t trx_no; + int num_blocks; + uint32_t tlli = 0xffeeddcc; + gprs_rlcmac_dl_tbf *dl_tbf; + int ts_no = 4; + bitvec *block; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + EGPRS_PD_AckNack_t *ack_nack; + RlcMacUplink_t ul_control_block; + gprs_rlc_v_b *prlcmvb; + gprs_rlc_dl_window *prlcdlwindow; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + /* ARQ II */ + bts->dl_arq_type = EGPRS_ARQ2; + + /* + * Over the Air message captured has been + * used to simulate this test case. During + * over the air testing, v_a was 1176, vs was 1288, + * max sns was 2048 + * and window size of 480. + */ + uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1, + 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f, + 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no); + dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + prlcdlwindow = &dl_tbf->m_window; + prlcmvb = &prlcdlwindow->m_v_b; + prlcdlwindow->m_v_s = 1288; + prlcdlwindow->m_v_a = 1176; + prlcdlwindow->set_sns(2048); + prlcdlwindow->set_ws(480); + prlcmvb->mark_unacked(1176); + prlcmvb->mark_unacked(1177); + prlcmvb->mark_unacked(1286); + prlcmvb->mark_unacked(1287); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + block = bitvec_alloc(23); + + bitvec_unpack(block, data_msg); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + decode_gsm_rlcmac_uplink(block, &ul_control_block); + + ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack; + + OSMO_ASSERT(prlcmvb->is_unacked(1176)); + OSMO_ASSERT(prlcmvb->is_unacked(1177)); + OSMO_ASSERT(prlcmvb->is_unacked(1286)); + OSMO_ASSERT(prlcmvb->is_unacked(1287)); + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &dl_tbf->m_window); + + dl_tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + /* + * TODO:status of BSN:1176,1177 shall be invalid + * status of BSN:1286,1287 shall be acked. + * both condition fails because of existing bug. Which shall be + * fixed in subsequent commit + */ + + OSMO_ASSERT(prlcmvb->is_unacked(1176)); + OSMO_ASSERT(prlcmvb->is_unacked(1177)); + OSMO_ASSERT(prlcmvb->is_unacked(1286)); + OSMO_ASSERT(prlcmvb->is_unacked(1287)); + + bitvec_free(block); + tbf_free(dl_tbf); + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2695,6 +2803,7 @@ test_tbf_puan_urbb_len(); test_tbf_update_ws(); test_tbf_li_decoding(); + test_egprs_tbf_epdan_out_of_rx_window(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0c9c877..877e0ad 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6521,3 +6521,39 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK +- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF! +DL packet loss of IMSI= / TLLI=0xffeeddcc: 100% +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index eb870ea..efcfdee 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -66,3 +66,5 @@ === end test_tbf_update_ws === === start test_tbf_li_decoding === === end test_tbf_li_decoding === +=== start test_egprs_tbf_epdan_out_of_rx_window === +=== end test_egprs_tbf_epdan_out_of_rx_window === -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Thu Sep 29 15:09:06 2016 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 29 Sep 2016 15:09:06 +0000 Subject: [PATCH] openbsc[master]: OML: Fixing static OML attribute tables Message-ID: Review at https://gerrit.osmocom.org/973 OML: Fixing static OML attribute tables - the OML attribute tables are hardcoded. To set variable parameters, the hardcoded data structure (tlv) is patched on byte level during runtime. This patch replaces that mechanism by setting up the TLV structures on runtime using mesage buffers (struct msgb) Change-Id: Ibeb34a84912d6cf695f553a34c69320fca7d08fa --- M openbsc/src/libbsc/bts_ipaccess_nanobts.c 1 file changed, 187 insertions(+), 184 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/73/973/1 diff --git a/openbsc/src/libbsc/bts_ipaccess_nanobts.c b/openbsc/src/libbsc/bts_ipaccess_nanobts.c index a6c8e29..b805eb1 100644 --- a/openbsc/src/libbsc/bts_ipaccess_nanobts.c +++ b/openbsc/src/libbsc/bts_ipaccess_nanobts.c @@ -100,94 +100,6 @@ }, }; -static unsigned char nanobts_attr_bts[] = { - NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73, - /* interference avg. period in numbers of SACCH multifr */ - NM_ATT_INTAVE_PARAM, 0x06, - /* conn fail based on SACCH error rate */ - NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10, - NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8, - NM_ATT_MAX_TA, 0x3f, - NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */ - NM_ATT_CCCH_L_T, 10, /* percent */ - NM_ATT_CCCH_L_I_P, 1, /* seconds */ - NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */ - NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */ - NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */ - NM_ATT_NY1, 10, /* 10 retransmissions of physical config */ - NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff, - NM_ATT_BSIC, HARDCODED_BSIC, - NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00, -}; - -static unsigned char nanobts_attr_radio[] = { - NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */ - NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff, -}; - -static unsigned char nanobts_attr_nse[] = { - NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */ - /* all timers in seconds */ - NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */ - 3, /* (un)blocking retries */ - 3, /* reset timer (Tns-reset) */ - 3, /* reset retries */ - 30, /* test timer (Tns-test) */ - 3, /* alive timer (Tns-alive) */ - 10, /* alive retrires */ - /* all timers in seconds, unless otherwise stated */ - NM_ATT_IPACC_BSSGP_CFG, 0, 11, - 3, /* blockimg timer (T1) */ - 3, /* blocking retries */ - 3, /* unblocking retries */ - 3, /* reset timer (T2) */ - 3, /* reset retries */ - 10, /* suspend timer (T3) in 100ms */ - 3, /* suspend retries */ - 10, /* resume timer (T4) in 100ms */ - 3, /* resume retries */ - 10, /* capability update timer (T5) */ - 3, /* capability update retries */ -}; - -static unsigned char nanobts_attr_cell[] = { - NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */ - NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2, - 5, /* repeat time (50ms) */ - 3, /* repeat count */ - NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */ - /* all timers in seconds, unless otherwise stated */ - NM_ATT_IPACC_RLC_CFG, 0, 9, - 20, /* T3142 */ - 5, /* T3169 */ - 5, /* T3191 */ - 160, /* T3193 (units of 10ms) */ - 5, /* T3195 */ - 10, /* N3101 */ - 4, /* N3103 */ - 8, /* N3105 */ - 15, /* RLC CV countdown */ - NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, /* CS1..CS4 */ - NM_ATT_IPACC_RLC_CFG_2, 0, 5, - 0x00, 250, /* T downlink TBF extension (0..500) */ - 0x00, 250, /* T uplink TBF extension (0..500) */ - 2, /* CS2 */ -#if 0 - /* EDGE model only, breaks older models. - * Should inquire the BTS capabilities */ - NM_ATT_IPACC_RLC_CFG_3, 0, 1, - 2, /* MCS2 */ -#endif -}; - -static unsigned char nanobts_attr_nsvc0[] = { - NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */ - NM_ATT_IPACC_NS_LINK_CFG, 0, 8, - 0x59, 0xd8, /* remote udp port (23000) */ - 192, 168, 100, 11, /* remote ip address */ - 0x59, 0xd8, /* local udp port (23000) */ -}; - static void patch_16(uint8_t *data, const uint16_t val) { memcpy(data, &val, sizeof(val)); @@ -198,112 +110,201 @@ memcpy(data, &val, sizeof(val)); } -/* - * Patch the various SYSTEM INFORMATION tables to update - * the LAI - */ -static void patch_nm_tables(struct gsm_bts *bts) +static struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts) { - uint8_t arfcn_low = bts->c0->arfcn & 0xff; - uint8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f; + struct msgb *msgb; + uint8_t buf[256]; + msgb = msgb_alloc(1024, "nanobts_attr_bts"); - /* patch ARFCN into BTS Attributes */ - nanobts_attr_bts[42] &= 0xf0; - nanobts_attr_bts[42] |= arfcn_high; - nanobts_attr_bts[43] = arfcn_low; + memcpy(buf, "\x55\x5b\x61\x67\x6d\x73", 6); + msgb_tv_fixed_put(msgb, NM_ATT_INTERF_BOUND, 6, buf); - /* patch the RACH attributes */ - if (bts->rach_b_thresh != -1) { - nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff; - } + /* interference avg. period in numbers of SACCH multifr */ + msgb_tv_put(msgb, NM_ATT_INTAVE_PARAM, 0x06); + /* conn fail based on SACCH error rate */ + buf[0] = 0x01; + buf[1] = get_radio_link_timeout(&bts->si_common.cell_options); + msgb_tl16v_put(msgb, NM_ATT_CONN_FAIL_CRIT, 2, buf); + + memcpy(buf, "\x1e\x24\x24\xa8\x34\x21\xa8", 7); + msgb_tv_fixed_put(msgb, NM_ATT_T200, 7, buf); + + msgb_tv_put(msgb, NM_ATT_MAX_TA, 0x3f); + + /* seconds */ + memcpy(buf, "\x00\x01\x0a", 3); + msgb_tv_fixed_put(msgb, NM_ATT_OVERL_PERIOD, 3, buf); + + /* percent */ + msgb_tv_put(msgb, NM_ATT_CCCH_L_T, 10); + + /* seconds */ + msgb_tv_put(msgb, NM_ATT_CCCH_L_I_P, 1); + + /* busy threshold in - dBm */ + buf[0] = 10; + if (bts->rach_b_thresh != -1) + buf[0] = bts->rach_b_thresh & 0xff; + msgb_tv_put(msgb, NM_ATT_RACH_B_THRESH, buf[0]); + + /* rach load averaging 1000 slots */ + buf[0] = 0x03; + buf[1] = 0xe8; if (bts->rach_ldavg_slots != -1) { - uint8_t avg_high = bts->rach_ldavg_slots & 0xff; - uint8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f; - - nanobts_attr_bts[35] = avg_high; - nanobts_attr_bts[36] = avg_low; + buf[0] = (bts->rach_ldavg_slots >> 8) & 0x0f; + buf[1] = bts->rach_ldavg_slots & 0xff; } + msgb_tv_fixed_put(msgb, NM_ATT_LDAVG_SLOTS, 2, buf); - /* patch BSIC */ - nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic; + /* miliseconds */ + msgb_tv_put(msgb, NM_ATT_BTS_AIR_TIMER, 128); - /* patch CGI */ - abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts); + /* 10 retransmissions of physical config */ + msgb_tv_put(msgb, NM_ATT_NY1, 10); - /* patch CON_FAIL_CRIT */ - nanobts_attr_bts[13] = - get_radio_link_timeout(&bts->si_common.cell_options); + buf[0] = (bts->c0->arfcn >> 8) & 0x0f; + buf[1] = bts->c0->arfcn & 0xff; + msgb_tv_fixed_put(msgb, NM_ATT_BCCH_ARFCN, 2, buf); - /* patch the power reduction */ - nanobts_attr_radio[1] = bts->c0->max_power_red / 2; + msgb_tv_put(msgb, NM_ATT_BSIC, bts->bsic); - /* patch NSEI */ - nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8; - nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff; - memcpy(nanobts_attr_nse+8, bts->gprs.nse.timer, - ARRAY_SIZE(bts->gprs.nse.timer)); - memcpy(nanobts_attr_nse+18, bts->gprs.cell.timer, - ARRAY_SIZE(bts->gprs.cell.timer)); + abis_nm_ipaccess_cgi(buf, bts); + msgb_tl16v_put(msgb, NM_ATT_IPACC_CGI, 7, buf); - /* patch NSVCI */ - nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8; - nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff; + return msgb; +} - /* patch IP address as SGSN IP */ - patch_16(nanobts_attr_nsvc0 + 8, - htons(bts->gprs.nsvc[0].remote_port)); - patch_32(nanobts_attr_nsvc0 + 10, - htonl(bts->gprs.nsvc[0].remote_ip)); - patch_16(nanobts_attr_nsvc0 + 14, - htons(bts->gprs.nsvc[0].local_port)); +static struct msgb *nanobts_attr_nse_get(struct gsm_bts *bts) +{ + struct msgb *msgb; + uint8_t buf[256]; + msgb = msgb_alloc(1024, "nanobts_attr_bts"); - /* patch BVCI */ - nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8; - nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff; - /* patch RAC */ - nanobts_attr_cell[3] = bts->gprs.rac; + /* NSEI 925 */ + buf[0] = bts->gprs.nse.nsei >> 8; + buf[1] = bts->gprs.nse.nsei & 0xff; + msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf); + + /* all timers in seconds */ + OSMO_ASSERT(ARRAY_SIZE(bts->gprs.nse.timer) < sizeof(buf)); + memcpy(buf, bts->gprs.nse.timer, ARRAY_SIZE(bts->gprs.nse.timer)); + msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf); + + /* all timers in seconds */ + buf[0] = 3; /* blockimg timer (T1) */ + buf[1] = 3; /* blocking retries */ + buf[2] = 3; /* unblocking retries */ + buf[3] = 3; /* reset timer (T2) */ + buf[4] = 3; /* reset retries */ + buf[5] = 10; /* suspend timer (T3) in 100ms */ + buf[6] = 3; /* suspend retries */ + buf[7] = 10; /* resume timer (T4) in 100ms */ + buf[8] = 3; /* resume retries */ + buf[9] = 10; /* capability update timer (T5) */ + buf[10] = 3; /* capability update retries */ + + OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf)); + memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer)); + msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf); + + return msgb; +} + +static struct msgb *nanobts_attr_cell_get(struct gsm_bts *bts) +{ + struct msgb *msgb; + uint8_t buf[256]; + msgb = msgb_alloc(1024, "nanobts_attr_bts"); + + /* routing area code */ + buf[0] = bts->gprs.rac; + msgb_tl16v_put(msgb, NM_ATT_IPACC_RAC, 1, buf); + + buf[0] = 5; /* repeat time (50ms) */ + buf[1] = 3; /* repeat count */ + msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf); + + /* BVCI 925 */ + buf[0] = bts->gprs.cell.bvci >> 8; + buf[1] = bts->gprs.cell.bvci & 0xff; + msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf); + + /* all timers in seconds, unless otherwise stated */ + buf[0] = 20; /* T3142 */ + buf[1] = 5; /* T3169 */ + buf[2] = 5; /* T3191 */ + buf[3] = 160; /* T3193 (units of 10ms) */ + buf[4] = 5; /* T3195 */ + buf[5] = 10; /* N3101 */ + buf[6] = 4; /* N3103 */ + buf[7] = 8; /* N3105 */ + buf[8] = 15; /* RLC CV countdown */ + msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf); if (bts->gprs.mode == BTS_GPRS_EGPRS) { - /* patch EGPRS coding schemes MCS 1..9 */ - nanobts_attr_cell[29] = 0x8f; - nanobts_attr_cell[30] = 0xff; + buf[0] = 0x8f; + buf[1] = 0xff; + } else { + buf[0] = 0x0f; + buf[1] = 0x00; } + msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf); + + buf[0] = 0; /* T downlink TBF extension (0..500, high byte) */ + buf[1] = 250; /* T downlink TBF extension (0..500, low byte) */ + buf[2] = 0; /* T uplink TBF extension (0..500, high byte) */ + buf[3] = 250; /* T uplink TBF extension (0..500, low byte) */ + buf[4] = 2; /* CS2 */ + msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf); + +#if 0 + /* EDGE model only, breaks older models. + * Should inquire the BTS capabilities */ + buf[0] = 2; /* MCS2 */ + msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf); +#endif + + return msgb; } -static uint8_t *nanobts_attr_bts_get(struct gsm_bts *bts, size_t *data_len) +static struct msgb *nanobts_attr_nscv_get(struct gsm_bts *bts) { - patch_nm_tables(bts); - *data_len = sizeof(nanobts_attr_bts); - return nanobts_attr_bts; + struct msgb *msgb; + uint8_t buf[256]; + msgb = msgb_alloc(1024, "nanobts_attr_bts"); + + /* 925 */ + buf[0] = bts->gprs.nsvc[0].nsvci >> 8; + buf[1] = bts->gprs.nsvc[0].nsvci & 0xff; + msgb_tl16v_put(msgb, NM_ATT_IPACC_NSVCI, 2, buf); + + /* remote udp port */ + patch_16(&buf[0], htons(bts->gprs.nsvc[0].remote_port)); + /* remote ip address */ + patch_32(&buf[2], htonl(bts->gprs.nsvc[0].remote_ip)); + /* local udp port (23000) */ + patch_16(&buf[6], htons(bts->gprs.nsvc[0].local_port)); + msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_LINK_CFG, 8, buf); + + return msgb; } -static uint8_t *nanobts_attr_nse_get(struct gsm_bts *bts, size_t *data_len) +static struct msgb *nanobts_attr_radio_get(struct gsm_bts *bts, + struct gsm_bts_trx *trx) { - patch_nm_tables(bts); - *data_len = sizeof(nanobts_attr_nse); - return nanobts_attr_nse; -} + struct msgb *msgb; + uint8_t buf[256]; + msgb = msgb_alloc(1024, "nanobts_attr_bts"); -static uint8_t *nanobts_attr_cell_get(struct gsm_bts *bts, size_t *data_len) -{ - patch_nm_tables(bts); - *data_len = sizeof(nanobts_attr_cell); - return nanobts_attr_cell; -} + /* number of -2dB reduction steps / Pn */ + msgb_tv_put(msgb, NM_ATT_RF_MAXPOWR_R, bts->c0->max_power_red / 2); -static uint8_t *nanobts_attr_nscv_get(struct gsm_bts *bts, size_t *data_len) -{ - patch_nm_tables(bts); - *data_len = sizeof(nanobts_attr_nsvc0); - return nanobts_attr_nsvc0; -} + buf[0] = trx->arfcn >> 8; + buf[1] = trx->arfcn & 0xff; + msgb_tl16v_put(msgb, NM_ATT_ARFCN_LIST, 2, buf); -static uint8_t *nanobts_attr_radio_get(struct gsm_bts *bts, size_t *data_len) -{ - patch_nm_tables(bts); - *data_len = sizeof(nanobts_attr_radio); - return nanobts_attr_radio; + return msgb; } /* Callback function to be called whenever we get a GSM 12.21 state change event */ @@ -318,8 +319,7 @@ struct gsm_bts_trx_ts *ts; struct gsm_bts_gprs_nsvc *nsvc; - uint8_t *data; - size_t data_len; + struct msgb *msgb; if (!is_ipaccess_bts(nsd->bts)) return 0; @@ -343,8 +343,9 @@ case NM_OC_BTS: bts = obj; if (new_state->availability == NM_AVSTATE_DEPENDENCY) { - data = nanobts_attr_bts_get(bts, &data_len); - abis_nm_set_bts_attr(bts, data, data_len); + msgb = nanobts_attr_bts_get(bts); + abis_nm_set_bts_attr(bts, msgb->data, msgb->len); + msgb_free(msgb); abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr, 0xff, 0xff, NM_STATE_UNLOCKED); @@ -385,9 +386,11 @@ if (bts->gprs.mode == BTS_GPRS_NONE) break; if (new_state->availability == NM_AVSTATE_DEPENDENCY) { - data = nanobts_attr_nse_get(bts, &data_len); + msgb = nanobts_attr_nse_get(bts); abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr, - 0xff, 0xff, data, data_len); + 0xff, 0xff, msgb->data, + msgb->len); + msgb_free(msgb); abis_nm_opstart(bts, obj_class, bts->bts_nr, 0xff, 0xff); } @@ -397,9 +400,11 @@ if (bts->gprs.mode == BTS_GPRS_NONE) break; if (new_state->availability == NM_AVSTATE_DEPENDENCY) { - data = nanobts_attr_cell_get(bts, &data_len); + msgb = nanobts_attr_cell_get(bts); abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr, - 0, 0xff, data, data_len); + 0, 0xff, msgb->data, + msgb->len); + msgb_free(msgb); abis_nm_opstart(bts, obj_class, bts->bts_nr, 0, 0xff); abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr, @@ -418,10 +423,11 @@ break; if ((new_state->availability == NM_AVSTATE_OFF_LINE) || (new_state->availability == NM_AVSTATE_DEPENDENCY)) { - data = nanobts_attr_nscv_get(bts, &data_len); + msgb = nanobts_attr_nscv_get(bts); abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr, nsvc->id, 0xff, - data, data_len); + msgb->data, msgb->len); + msgb_free(msgb); abis_nm_opstart(bts, obj_class, bts->bts_nr, nsvc->id, 0xff); abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr, @@ -471,12 +477,9 @@ */ int rc_state = trx->mo.nm_state.administrative; /* Patch ARFCN into radio attribute */ - size_t data_len; - uint8_t *data = nanobts_attr_radio_get(trx->bts, &data_len); - data[5] &= 0xf0; - data[5] |= trx->arfcn >> 8; - data[6] = trx->arfcn & 0xff; - abis_nm_set_radio_attr(trx, data, data_len); + struct msgb *msgb = nanobts_attr_radio_get(trx->bts, trx); + abis_nm_set_radio_attr(trx, msgb->data, msgb->len); + msgb_free(msgb); abis_nm_chg_adm_state(trx->bts, foh->obj_class, trx->bts->bts_nr, trx->nr, 0xff, rc_state); -- To view, visit https://gerrit.osmocom.org/973 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibeb34a84912d6cf695f553a34c69320fca7d08fa Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Sep 29 23:29:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 23:29:15 +0000 Subject: [PATCH] libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh Message-ID: Review at https://gerrit.osmocom.org/974 configure: add --enable-sanitize, use in jenkins.sh --enable-sanitize adds address sanitizer flags to the entire build. Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d --- M configure.ac M contrib/jenkins.sh 2 files changed, 15 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/74/974/1 diff --git a/configure.ac b/configure.ac index 1b62278..29a3ad6 100644 --- a/configure.ac +++ b/configure.ac @@ -199,6 +199,20 @@ AC_DEFINE([PANIC_INFLOOP],[1],[Use infinite loop on panic rather than fprintf/abort]) fi +AC_ARG_ENABLE(sanitize, + [AS_HELP_STRING( + [--enable-sanitize], + [Compile with address sanitizer enabled], + )], + [sanitize=$enableval], [sanitize="no"]) +if test x"$sanitize" = x"yes" +then + CFLAGS+=" -fsanitize=address -fsanitize=undefined" + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" + ASAN_OPTIONS="detect_leaks=0" + UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" +fi + AC_OUTPUT( libosmocore.pc libosmocodec.pc diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..94f3f4f 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -3,6 +3,6 @@ set -ex autoreconf --install --force -./configure --enable-static +./configure --enable-static --enable-sanitize $MAKE $PARALLEL_MAKE $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 29 23:29:15 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 23:29:15 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Message-ID: Review at https://gerrit.osmocom.org/975 NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/975/1 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Sep 29 23:33:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 29 Sep 2016 23:33:08 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/975 to look at the new patch set (#2). NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d --- M contrib/jenkins.sh M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 3 files changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/975/2 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 94f3f4f..69a29a9 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -4,5 +4,5 @@ autoreconf --install --force ./configure --enable-static --enable-sanitize -$MAKE $PARALLEL_MAKE +$MAKE V=1 $PARALLEL_MAKE $MAKE distcheck diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:02:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:02:58 +0000 Subject: [PATCH] libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/974 to look at the new patch set (#2). configure: add --enable-sanitize, use in jenkins.sh --enable-sanitize adds address sanitizer flags to the entire build. Add this flag to jenkins.sh's configure step. To ensure that we get the sanitize results, add 'make check' to jenkins ('make distcheck' has its own configure step, apparently, which omits --enable-sanitize) Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d --- M configure.ac M contrib/jenkins.sh 2 files changed, 16 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/74/974/2 diff --git a/configure.ac b/configure.ac index 1b62278..29a3ad6 100644 --- a/configure.ac +++ b/configure.ac @@ -199,6 +199,20 @@ AC_DEFINE([PANIC_INFLOOP],[1],[Use infinite loop on panic rather than fprintf/abort]) fi +AC_ARG_ENABLE(sanitize, + [AS_HELP_STRING( + [--enable-sanitize], + [Compile with address sanitizer enabled], + )], + [sanitize=$enableval], [sanitize="no"]) +if test x"$sanitize" = x"yes" +then + CFLAGS+=" -fsanitize=address -fsanitize=undefined" + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" + ASAN_OPTIONS="detect_leaks=0" + UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" +fi + AC_OUTPUT( libosmocore.pc libosmocodec.pc diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e53c6d8 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -3,6 +3,6 @@ set -ex autoreconf --install --force -./configure --enable-static -$MAKE $PARALLEL_MAKE +./configure --enable-static --enable-sanitize +$MAKE $PARALLEL_MAKE check $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:02:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:02:58 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/975 to look at the new patch set (#3). NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d --- M contrib/jenkins.sh M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 3 files changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/975/3 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e53c6d8..c262ff0 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -4,5 +4,5 @@ autoreconf --install --force ./configure --enable-static --enable-sanitize -$MAKE $PARALLEL_MAKE check +$MAKE V=1 $PARALLEL_MAKE check $MAKE distcheck diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:07:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:07:20 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/975 to look at the new patch set (#4). NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d --- M contrib/jenkins.sh M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 3 files changed, 7 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/975/4 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e53c6d8..56b8a98 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -4,5 +4,7 @@ autoreconf --install --force ./configure --enable-static --enable-sanitize -$MAKE $PARALLEL_MAKE check -$MAKE distcheck +$MAKE V=1 $PARALLEL_MAKE check \ + || cat-testlogs.sh +$MAKE distcheck \ + || cat-testlogs.sh diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:13:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:13:34 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: add sanitize options to jenkins run Message-ID: Review at https://gerrit.osmocom.org/976 jenkins.sh: add sanitize options to jenkins run Add -fsanitize flags and ASAN/UBSAN options. Do 'make check' besides 'make distcheck'. Change-Id: I9911e6b189a0d5f2d739e81d196cc323a9b85e7d --- M contrib/jenkins.sh 1 file changed, 12 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/976/1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..ec92004 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -4,5 +4,15 @@ autoreconf --install --force ./configure --enable-static -$MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE $PARALLEL_MAKE \ + CFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + ASAN_OPTIONS="detect_leaks=0" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" \ + check \ + || cat-testlogs.sh +$MAKE \ + CFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + ASAN_OPTIONS="detect_leaks=0" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" \ + distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9911e6b189a0d5f2d739e81d196cc323a9b85e7d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:14:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:14:48 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Message-ID: Review at https://gerrit.osmocom.org/977 NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: Ib1b5892d4eebecb4786da294307824cbdbfa523a --- M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 2 files changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/77/977/1 diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/977 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib1b5892d4eebecb4786da294307824cbdbfa523a Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:26:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:26:08 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: add -fsanitize flags, add 'make check' Message-ID: Review at https://gerrit.osmocom.org/978 jenkins.sh: add -fsanitize flags, add 'make check' Change-Id: I1692a4730e83b71f2976651993e94de0fe060b8e --- M contrib/jenkins.sh 1 file changed, 6 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/978/1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..6241711 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -2,7 +2,12 @@ set -ex +export CFLAGS="-fsanitize=address -fsanitize=undefined" +export CPPFLAGS="-fsanitize=address -fsanitize=undefined" +export ASAN_OPTIONS="detect_leaks=0" +export UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" + autoreconf --install --force ./configure --enable-static -$MAKE $PARALLEL_MAKE +$MAKE $PARALLEL_MAKE check $MAKE distcheck -- To view, visit https://gerrit.osmocom.org/978 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1692a4730e83b71f2976651993e94de0fe060b8e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:26:08 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:26:08 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Message-ID: Review at https://gerrit.osmocom.org/979 NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I8ecaeec67474dd0e8acb0ffc1b1594d0c4b9911d --- M contrib/jenkins.sh M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 3 files changed, 7 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/979/1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 6241711..d8e4867 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -9,5 +9,7 @@ autoreconf --install --force ./configure --enable-static -$MAKE $PARALLEL_MAKE check -$MAKE distcheck +$MAKE $PARALLEL_MAKE check \ + || cat-testlogs.sh +$MAKE distcheck \ + || cat-testlogs.sh diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/979 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8ecaeec67474dd0e8acb0ffc1b1594d0c4b9911d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:53:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:53:42 +0000 Subject: libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 I have tested various ways of switching on -fsanitize: (1) adding the flags with a ./configure switch (this patch). (2) in jenkins.sh, add flags to 'make' invocation. (3) in jenkins.sh, export flags before running ./configure. I would have liked this to work on both the linux_amd64 slave as well as the FreeBSD slave, but the FreeBSD slave doesn't seem to like ASAN, at least that's how I interpret the test runs: works as expected on: (1) (2) (3) linux yes yes yes FreeBSD no no no What happens on FreeBSD? (1) (2) (3) clean build passes yes no no dirty build passes yes no no On FreeBSD: For (1), a clean build passes, but sanity fail is not detected. This should fail: https://jenkins.osmocom.org/jenkins/job/libosmocore-gerrit/261/ For (2), a clean build fails. This should pass: https://jenkins.osmocom.org/jenkins/job/libosmocore-gerrit/262/ Instead we get undefined reference to asan symbols for tests compilation. For (3), a clean build fails. This should pass: https://jenkins.osmocom.org/jenkins/job/libosmocore-gerrit/264/ Instead we get a "C compiler cannot create executables" So this patch here (1) successfully detects sanitize failures on linux, and just passes everything on FreeBSD, be it sane or not. Which means we can apply this without introducing problems on FreeBSD. I favor this patch over the other methods. Though I don't understand exactly why FreeBSD fails with ASAN (gmake? cc instead of gcc?). This patch also has the advantage of being most convenient: just pass a configure option of --enable-sanitize and done. The verbose options are hidden in configure.ac. (I hope they all get through, but the result looks good.) -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:55:38 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:55:38 +0000 Subject: libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:55:48 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:55:48 +0000 Subject: libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/977 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib1b5892d4eebecb4786da294307824cbdbfa523a Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:55:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:55:55 +0000 Subject: libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/979 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8ecaeec67474dd0e8acb0ffc1b1594d0c4b9911d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:56:18 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:56:18 +0000 Subject: libosmocore[master]: jenkins.sh: add sanitize options to jenkins run In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 fails to pass clean build on FreeBSD -- To view, visit https://gerrit.osmocom.org/976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9911e6b189a0d5f2d739e81d196cc323a9b85e7d Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:56:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:56:37 +0000 Subject: libosmocore[master]: jenkins.sh: add -fsanitize flags, add 'make check' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 fails to pass clean build on FreeBSD -- To view, visit https://gerrit.osmocom.org/978 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1692a4730e83b71f2976651993e94de0fe060b8e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:57:22 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:57:22 +0000 Subject: [ABANDON] openbsc[master]: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: NOT FOR MERGE: testrun for vty_test_runner.py on jenkins ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I5f93af0155a1f465cce1f505098efb5e5e2aa9cb Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:11 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:11 +0000 Subject: libosmocore[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:13 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:13 +0000 Subject: [MERGED] libosmocore[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: jenkins.sh: output all test logs when 'make check' failed ...................................................................... jenkins.sh: output all test logs when 'make check' failed Assume that cat-testlogs.sh from osmo-ci is installed in $HOME/osmo-ci/scripts, and call from jenkins.sh upon 'make check' failure. Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be --- M contrib/jenkins.sh 1 file changed, 3 insertions(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 5c69da6..e9f63e4 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex autoreconf --install --force ./configure --enable-static $MAKE $PARALLEL_MAKE -$MAKE distcheck +$MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/866 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I18a08e7ade1a53783d5a4171fe825f61b49457be Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:24 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:24 +0000 Subject: osmo-iuh[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/868 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae Gerrit-PatchSet: 2 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:26 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:26 +0000 Subject: [MERGED] osmo-iuh[master]: jenkins.sh: output all test logs when 'make check' failed In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: jenkins.sh: output all test logs when 'make check' failed ...................................................................... jenkins.sh: output all test logs when 'make check' failed Assume that cat-testlogs.sh from osmo-ci is installed in $HOME/osmo-ci/scripts, and call from jenkins.sh upon 'make check' failure. Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae --- M contrib/jenkins.sh 1 file changed, 5 insertions(+), 2 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 8021bbd..b19f0c6 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export PATH="$PATH:$HOME/osmo-ci/scripts" set -ex @@ -74,5 +75,7 @@ fi $MAKE $PARALLEL_MAKE -LD_LIBRARY_PATH="$inst/lib" $MAKE check -LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck +LD_LIBRARY_PATH="$inst/lib" $MAKE check \ + || cat-testlogs.sh +LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/868 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6ee37ae638aa0b95222e5c0ec78474fab1f8cfae Gerrit-PatchSet: 3 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:34 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:34 +0000 Subject: [ABANDON] libosmocore[master]: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: NOT FOR MERGE: testrun for cat_testlogs.sh: break a test expectation ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/871 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I6ccc430e27b2d59dd97b37d5130347dac1329dac Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 00:58:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 00:58:49 +0000 Subject: [ABANDON] osmo-iuh[master]: NOT FOR MERGE: testrun for cat-testlogs.sh: break a test exp... In-Reply-To: References: Message-ID: Neels Hofmeyr has abandoned this change. Change subject: NOT FOR MERGE: testrun for cat-testlogs.sh: break a test expectation ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/954 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I906d7547c055e7943323a472a982d3bbf9c36228 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:01:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:01:49 +0000 Subject: [PATCH] libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/974 to look at the new patch set (#3). configure: add --enable-sanitize, use in jenkins.sh --enable-sanitize adds address sanitizer flags to the entire build. Add this flag to jenkins.sh's configure step. To ensure that we get the sanitize results, add 'make check' to jenkins ('make distcheck' has its own configure step, apparently, which omits --enable-sanitize) Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d --- M configure.ac M contrib/jenkins.sh 2 files changed, 17 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/74/974/3 diff --git a/configure.ac b/configure.ac index 1b62278..29a3ad6 100644 --- a/configure.ac +++ b/configure.ac @@ -199,6 +199,20 @@ AC_DEFINE([PANIC_INFLOOP],[1],[Use infinite loop on panic rather than fprintf/abort]) fi +AC_ARG_ENABLE(sanitize, + [AS_HELP_STRING( + [--enable-sanitize], + [Compile with address sanitizer enabled], + )], + [sanitize=$enableval], [sanitize="no"]) +if test x"$sanitize" = x"yes" +then + CFLAGS+=" -fsanitize=address -fsanitize=undefined" + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" + ASAN_OPTIONS="detect_leaks=0" + UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" +fi + AC_OUTPUT( libosmocore.pc libosmocodec.pc diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e9f63e4..742963c 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -4,7 +4,8 @@ set -ex autoreconf --install --force -./configure --enable-static -$MAKE $PARALLEL_MAKE +./configure --enable-static --enable-sanitize +$MAKE $PARALLEL_MAKE check \ + || cat-testlogs.sh $MAKE distcheck \ || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:01:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:01:49 +0000 Subject: [PATCH] libosmocore[master]: NOT FOR MERGE: introduce ASAN failure to test jenkins.sh In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/975 to look at the new patch set (#5). NOT FOR MERGE: introduce ASAN failure to test jenkins.sh Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d --- M contrib/jenkins.sh M tests/bits/bitrev_test.c M tests/bits/bitrev_test.ok 3 files changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/975/5 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 742963c..6fb0c6b 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,7 +5,7 @@ autoreconf --install --force ./configure --enable-static --enable-sanitize -$MAKE $PARALLEL_MAKE check \ +$MAKE V=1 $PARALLEL_MAKE check \ || cat-testlogs.sh $MAKE distcheck \ || cat-testlogs.sh diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c index ed3939a..e84a898 100644 --- a/tests/bits/bitrev_test.c +++ b/tests/bits/bitrev_test.c @@ -300,9 +300,7 @@ sh_chk(in1, ARRAY_SIZE(in1), offs, true); sh_chk(in1, ARRAY_SIZE(in1), offs, false); sh_chk(in2, ARRAY_SIZE(in2), offs, true); - /* in2 is too short to shift left 12 nibbles */ - if (offs < 12) - sh_chk(in2, ARRAY_SIZE(in2), offs, false); + sh_chk(in2, ARRAY_SIZE(in2), offs, false); } return 0; } diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok index d2fb12c..f58f070 100644 --- a/tests/bits/bitrev_test.ok +++ b/tests/bits/bitrev_test.ok @@ -156,3 +156,5 @@ OUT: 00dcafedeadb [6] R IN: b00bbabeface, nibble 12: OUT: 0b00bbabefac +[6] L IN: b00bbabeface, nibble 12: + OUT: 00bbabeface0 -- To view, visit https://gerrit.osmocom.org/975 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b0b22d5163bd1243f6ea0e25bce15e0a626000d Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:03:55 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:03:55 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: add sanitize options to jenkins run In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/976 to look at the new patch set (#2). jenkins.sh: add sanitize options to jenkins run Add -fsanitize flags and ASAN/UBSAN options. Do 'make check' besides 'make distcheck'. Change-Id: I9911e6b189a0d5f2d739e81d196cc323a9b85e7d --- M contrib/jenkins.sh 1 file changed, 12 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/976/2 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e9f63e4..9662dae 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,6 +5,15 @@ autoreconf --install --force ./configure --enable-static -$MAKE $PARALLEL_MAKE -$MAKE distcheck \ - || cat-testlogs.sh +$MAKE $PARALLEL_MAKE \ + CFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + ASAN_OPTIONS="detect_leaks=0" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" \ + check \ + || cat-testlogs.sh +$MAKE \ + CFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" \ + ASAN_OPTIONS="detect_leaks=0" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" \ + distcheck \ + || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9911e6b189a0d5f2d739e81d196cc323a9b85e7d Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:06:16 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:06:16 +0000 Subject: [PATCH] libosmocore[master]: jenkins.sh: add -fsanitize flags, add 'make check' In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/978 to look at the new patch set (#2). jenkins.sh: add -fsanitize flags, add 'make check' Change-Id: I1692a4730e83b71f2976651993e94de0fe060b8e --- M contrib/jenkins.sh 1 file changed, 7 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/978/2 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index e9f63e4..154ef43 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -3,8 +3,14 @@ set -ex +export CFLAGS="-fsanitize=address -fsanitize=undefined" +export CPPFLAGS="-fsanitize=address -fsanitize=undefined" +export ASAN_OPTIONS="detect_leaks=0" +export UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" + autoreconf --install --force ./configure --enable-static -$MAKE $PARALLEL_MAKE +$MAKE $PARALLEL_MAKE check \ + || cat-testlogs.sh $MAKE distcheck \ || cat-testlogs.sh -- To view, visit https://gerrit.osmocom.org/978 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I1692a4730e83b71f2976651993e94de0fe060b8e Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:07:14 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:07:14 +0000 Subject: libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (see long comment on patch set 2) -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 01:14:41 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 01:14:41 +0000 Subject: [PATCH] openbsc[master]: log CTRL bind only once Message-ID: Review at https://gerrit.osmocom.org/980 log CTRL bind only once After libosmocore 38d232ee5d2ceb045d9ad6d3a23afcb4972523f7 which outputs 'CTRL at ' from ctrl_interface_setup_dynip(), there's no need to log the CTRL bind here anymore. Change-Id: I1a874efe365a1ecf8ec37b058215b95b9a635ec2 --- M openbsc/src/gprs/sgsn_main.c M openbsc/src/osmo-bsc/osmo_bsc_main.c M openbsc/src/osmo-bsc_nat/bsc_nat.c M openbsc/src/osmo-nitb/bsc_hack.c 4 files changed, 0 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/80/980/1 diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 93848f5..822c359 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -389,8 +389,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DGPRS, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_SGSN); ctrl = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_SGSN); if (!ctrl) { diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 2ee5fb4..d3128e4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -229,8 +229,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); bsc_gsmnet->ctrl = bsc_controlif_setup(bsc_gsmnet, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 57cc8b3..6ae8c05 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1669,8 +1669,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNAT, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BSC_NAT); nat->ctrl = bsc_nat_controlif_setup(nat, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BSC_NAT); if (!nat->ctrl) { diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 8e1ddae..28dbb6f 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -313,8 +313,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); bsc_gsmnet->ctrl = bsc_controlif_setup(bsc_gsmnet, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); -- To view, visit https://gerrit.osmocom.org/980 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1a874efe365a1ecf8ec37b058215b95b9a635ec2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 06:24:57 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 30 Sep 2016 06:24:57 +0000 Subject: osmo-pcu[master]: EGPRS: fix for EPDAN out of window In-Reply-To: References: Message-ID: Patch Set 2: (4 comments) https://gerrit.osmocom.org/#/c/862/2/src/rlc.cpp File src/rlc.cpp: Line 108: unsigned num_blocks = rbb->cur_bit > (unsigned)distance() > can distance() be negative? Casting a negative value to unsigned is invitin The distance is supposed to be positive. But earlier return type is signed. so there needs to be type casting. https://gerrit.osmocom.org/#/c/862/2/src/tbf_dl.cpp File src/tbf_dl.cpp: Line 849: ? m_window.distance() : strlen(show_rbb); > don't call strlen twice. (Does the compiler optimize this? I guess not.) Ok. I will modify the patch. Line 929: unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance() > unsigned distance The distance is supposed to be positive. But earlier return type is signed. so there needs to be type casting. Line 953: "V(A)..V(S) range %s\n", tbf_name(this)); > Do above "this might happen..." comments need to be adjusted, or do they st This if condition shall never be hit after this fix. so I will remove the conditional along with comments. -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 09:47:03 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 09:47:03 +0000 Subject: [PATCH] osmo-bts[master]: LC15: Clarify msgb ownership / fix memory leaks Message-ID: Review at https://gerrit.osmocom.org/981 LC15: Clarify msgb ownership / fix memory leaks This is similar to 21b020b33633683d7c785af15c773aab0f79d0de which changes the way msgb is allocated/freed in sysmobts. Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087 --- M src/osmo-bts-litecell15/l1_if.c 1 file changed, 31 insertions(+), 22 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/81/981/1 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..cf7ce58 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -399,6 +399,7 @@ LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d " "chan_nr %d link_id %d\n", l1sap->oph.primitive, l1sap->oph.operation, chan_nr, link_id); + msgb_free(l1msg); return -EINVAL; } @@ -421,13 +422,10 @@ empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } - /* free the msgb holding the L1SAP primitive */ - msgb_free(msg); - /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) { LOGP(DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); - msgb_free(msg); + msgb_free(l1msg); } return 0; @@ -509,8 +507,6 @@ return ph_tch_req(trx, l1sap->oph.msg, l1sap); } - if (msg) - msgb_free(msg); return 0; } @@ -554,7 +550,6 @@ l1if_rsl_deact_sacch(lchan); else l1if_rsl_chan_rel(lchan); - msgb_free(msg); break; default: LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", @@ -571,6 +566,8 @@ struct msgb *msg = l1sap->oph.msg; int rc = 0; + /* called functions MUST NOT take ownership of msgb, as it is + * free()d below */ switch (OSMO_PRIM_HDR(&l1sap->oph)) { case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): rc = ph_data_req(trx, msg, l1sap); @@ -587,13 +584,14 @@ rc = -EINVAL; } - if (rc) - msgb_free(msg); + msgb_free(msg); + return rc; } static int handle_mph_time_ind(struct lc15l1_hdl *fl1, - GsmL1_MphTimeInd_t *time_ind) + GsmL1_MphTimeInd_t *time_ind, + struct msgb *msg) { struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1); struct gsm_bts *bts = trx->bts; @@ -615,6 +613,8 @@ PRIM_OP_INDICATION, NULL); l1sap.u.info.type = PRIM_INFO_TIME; l1sap.u.info.u.time_ind.fn = fn; + + msgb_free(msg); return l1sap_up(trx, &l1sap); } @@ -758,6 +758,8 @@ link_id = 0x40; else link_id = 0; + /* recycle the msgb and use it for the L1 primitive, + * which means that we (or our caller) must not free it */ rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive\n"); @@ -824,6 +826,8 @@ msgb_free(resp_msg); } + /* free the msgb, as we have not handed it to l1sap and thus + * need to release its memory */ msgb_free(l1p_msg); return 0; @@ -854,6 +858,8 @@ l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 100); l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1); + /* l1sap wants to take msgb ownership. However, as there is no + * msg, it will msgb_free(l1sap.oph.msg == NULL) */ return l1sap_up(trx, &l1sap); } @@ -999,29 +1005,28 @@ GsmL1_Prim_t *l1p = msgb_l1prim(msg); int rc = 0; + /* all the below called functions must take ownership of the msgb */ switch (l1p->id) { case GsmL1_PrimId_MphTimeInd: - rc = handle_mph_time_ind(fl1, &l1p->u.mphTimeInd); + rc = handle_mph_time_ind(fl1, &l1p->u.mphTimeInd, msg); break; case GsmL1_PrimId_MphSyncInd: break; case GsmL1_PrimId_PhConnectInd: break; case GsmL1_PrimId_PhReadyToSendInd: - return handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, + rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, msg); + break; case GsmL1_PrimId_PhDataInd: - return handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); + rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); + break; case GsmL1_PrimId_PhRaInd: - return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); + rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); break; default: break; } - - /* Special return value '1' means: do not free */ - if (rc != 1) - msgb_free(msg); return rc; } @@ -1056,10 +1061,12 @@ llist_for_each_entry(wlc, &fl1h->wlc_list, list) { if (is_prim_compat(l1p, wlc)) { llist_del(&wlc->list); - if (wlc->cb) + if (wlc->cb) { + /* call-back function must take + * ownership of msgb */ rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg, wlc->cb_data); - else { + } else { rc = 0; msgb_free(msg); } @@ -1087,10 +1094,12 @@ * sending the same primitive */ if (wlc->is_sys_prim && sysp->id == wlc->conf_prim_id) { llist_del(&wlc->list); - if (wlc->cb) + if (wlc->cb) { + /* call-back function must take + * ownership of msgb */ rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg, wlc->cb_data); - else { + } else { rc = 0; msgb_free(msg); } -- To view, visit https://gerrit.osmocom.org/981 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Fri Sep 30 10:06:19 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 10:06:19 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#9). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 32 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/9 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index cf7ce58..a4378c1 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -441,6 +441,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -464,17 +465,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -502,7 +506,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 08c64ab..4677b1a 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..09627af 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,17 +460,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -497,7 +501,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 3eb9bfd..f7522ba 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 9 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 10:24:18 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 30 Sep 2016 10:24:18 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: fix for EPDAN out of window In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/862 to look at the new patch set (#3). EGPRS: fix for EPDAN out of window Fix alignment of EPDAN outside the RLC transmit window, according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that a bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored. Without this fix PCU was dropping the EPDAN message and not updating the status of BSNs which are inside the RLC window. This patch updates the status of the BSNs which are inside the window and ignores the remaining bits. Related: OS#1789 Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 --- M src/rlc.cpp M src/tbf_dl.cpp M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err 4 files changed, 129 insertions(+), 37 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/62/862/3 diff --git a/src/rlc.cpp b/src/rlc.cpp index ee2635a..b544d6a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -105,7 +105,8 @@ uint16_t first_bsn, uint16_t *lost, uint16_t *received) { - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)distance() + ? distance() : rbb->cur_bit; unsigned bsn; /* first_bsn is in range V(A)..V(S) */ diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 457f2c9..a0874d4 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -847,6 +847,9 @@ unsigned received_packets = 0, lost_packets = 0; unsigned num_blocks = strlen(show_rbb); + num_blocks = num_blocks > (unsigned)m_window.distance() + ? m_window.distance() : num_blocks; + /* SSN - 1 is in range V(A)..V(S)-1 */ for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { bool is_received; @@ -919,13 +922,13 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn, const struct bitvec *rbb) { - int16_t dist; /* must be signed */ uint16_t lost = 0, received = 0; char show_v_b[RLC_MAX_SNS + 1]; char show_rbb[RLC_MAX_SNS + 1]; int error_rate; struct ana_result ana_res; - unsigned num_blocks = rbb->cur_bit; + unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance() + ? m_window.distance() : rbb->cur_bit; unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks); Decoding::extract_rbb(rbb, show_rbb); @@ -933,25 +936,6 @@ LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" "(BSN=%d) R=ACK I=NACK\n", first_bsn, show_rbb, m_window.mod_sns(behind_last_bsn - 1)); - - /* apply received array to receive state (first_bsn..behind_last_bsn-1) */ - if (num_blocks > 0) { - /* calculate distance of ssn from V(S) */ - dist = m_window.mod_sns(m_window.v_s() - behind_last_bsn); - /* check if distance is less than distance V(A)..V(S) */ - if (dist >= m_window.distance()) { - /* this might happpen, if the downlink assignment - * was not received by ms and the ack refers - * to previous TBF - * FIXME: we should implement polling for - * control ack! - * TODO: check whether this FIXME still makes sense - */ - LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " - "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); - return 1; /* indicate to free TBF */ - } - } error_rate = analyse_errors(show_rbb, behind_last_bsn, &ana_res); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3ae9cbe..f9af05d 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -2108,17 +2108,11 @@ dl_tbf->rcvd_dl_ack( ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, bsn_begin, &bits); - /* - * TODO:status of BSN:1176,1177 shall be invalid - * status of BSN:1286,1287 shall be acked. - * both condition fails because of existing bug. Which shall be - * fixed in subsequent commit - */ - OSMO_ASSERT(prlcmvb->is_unacked(1176)); - OSMO_ASSERT(prlcmvb->is_unacked(1177)); - OSMO_ASSERT(prlcmvb->is_unacked(1286)); - OSMO_ASSERT(prlcmvb->is_unacked(1287)); + OSMO_ASSERT(prlcmvb->is_invalid(1176)); + OSMO_ASSERT(prlcmvb->is_invalid(1177)); + OSMO_ASSERT(prlcmvb->is_acked(1286)); + OSMO_ASSERT(prlcmvb->is_acked(1287)); bitvec_free(block); tbf_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 877e0ad..c25de2d 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -446,7 +446,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=85)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=20) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=127, info='RRRRRRRRRRRRRRRRRRRRR$..........................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRR...........................................' - got ack for BSN=20 - got ack for BSN=19 - got ack for BSN=18 @@ -485,7 +485,7 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=86)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=21) R=ACK I=NACK -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=20, info='R$..............................................................' +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=21, info='R...............................................................' - got ack for BSN=21 - V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -6547,9 +6547,122 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge -- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK -- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF! -DL packet loss of IMSI= / TLLI=0xffeeddcc: 100% +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1287) R=ACK I=NACK +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=1176:1288, lost=73, recv=39, skipped=0, bsn=1944, info='RRRRRRRRRRRRRRRRRRRRRRRRRRLRRRLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRR................................................................................................................................................................................................................................................................................................................................................................................' +- got ack for BSN=1176 +- got ack for BSN=1177 +- got ack for BSN=1178 +- got ack for BSN=1179 +- got ack for BSN=1180 +- got ack for BSN=1181 +- got ack for BSN=1182 +- got ack for BSN=1183 +- got ack for BSN=1184 +- got ack for BSN=1185 +- got NACK for BSN=1186 +- got NACK for BSN=1187 +- got NACK for BSN=1188 +- got NACK for BSN=1189 +- got NACK for BSN=1190 +- got NACK for BSN=1191 +- got NACK for BSN=1192 +- got NACK for BSN=1193 +- got NACK for BSN=1194 +- got NACK for BSN=1195 +- got NACK for BSN=1196 +- got NACK for BSN=1197 +- got NACK for BSN=1198 +- got NACK for BSN=1199 +- got NACK for BSN=1200 +- got NACK for BSN=1201 +- got NACK for BSN=1202 +- got NACK for BSN=1203 +- got NACK for BSN=1204 +- got NACK for BSN=1205 +- got NACK for BSN=1206 +- got NACK for BSN=1207 +- got NACK for BSN=1208 +- got NACK for BSN=1209 +- got NACK for BSN=1210 +- got NACK for BSN=1211 +- got NACK for BSN=1212 +- got NACK for BSN=1213 +- got NACK for BSN=1214 +- got NACK for BSN=1215 +- got NACK for BSN=1216 +- got NACK for BSN=1217 +- got NACK for BSN=1218 +- got NACK for BSN=1219 +- got NACK for BSN=1220 +- got NACK for BSN=1221 +- got NACK for BSN=1222 +- got NACK for BSN=1223 +- got NACK for BSN=1224 +- got NACK for BSN=1225 +- got NACK for BSN=1226 +- got NACK for BSN=1227 +- got NACK for BSN=1228 +- got NACK for BSN=1229 +- got NACK for BSN=1230 +- got NACK for BSN=1231 +- got NACK for BSN=1232 +- got NACK for BSN=1233 +- got NACK for BSN=1234 +- got NACK for BSN=1235 +- got NACK for BSN=1236 +- got NACK for BSN=1237 +- got NACK for BSN=1238 +- got NACK for BSN=1239 +- got NACK for BSN=1240 +- got NACK for BSN=1241 +- got NACK for BSN=1242 +- got NACK for BSN=1243 +- got NACK for BSN=1244 +- got NACK for BSN=1245 +- got NACK for BSN=1246 +- got NACK for BSN=1247 +- got NACK for BSN=1248 +- got NACK for BSN=1249 +- got NACK for BSN=1250 +- got NACK for BSN=1251 +- got NACK for BSN=1252 +- got NACK for BSN=1253 +- got NACK for BSN=1254 +- got NACK for BSN=1255 +- got NACK for BSN=1256 +- got NACK for BSN=1257 +- got ack for BSN=1258 +- got ack for BSN=1259 +- got ack for BSN=1260 +- got NACK for BSN=1261 +- got ack for BSN=1262 +- got ack for BSN=1263 +- got ack for BSN=1264 +- got ack for BSN=1265 +- got ack for BSN=1266 +- got ack for BSN=1267 +- got ack for BSN=1268 +- got ack for BSN=1269 +- got ack for BSN=1270 +- got ack for BSN=1271 +- got ack for BSN=1272 +- got ack for BSN=1273 +- got ack for BSN=1274 +- got ack for BSN=1275 +- got ack for BSN=1276 +- got ack for BSN=1277 +- got ack for BSN=1278 +- got ack for BSN=1279 +- got ack for BSN=1280 +- got ack for BSN=1281 +- got ack for BSN=1282 +- got ack for BSN=1283 +- got ack for BSN=1284 +- got ack for BSN=1285 +- got ack for BSN=1286 +- got ack for BSN=1287 +- V(B): (V(A)=1186)"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAANAAAAAAAAAAAAAAAAAAAAAAAAAA"(V(S)-1=1287) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid +DL packet loss of IMSI= / TLLI=0xffeeddcc: 78% TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 30 10:25:31 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 30 Sep 2016 10:25:31 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Patch Set 3: (1 comment) https://gerrit.osmocom.org/#/c/861/3//COMMIT_MSG Commit Message: Line 17: the bug fix in a subsequent commit put a "." at the end of sentense -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 3 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 10:25:45 2016 From: gerrit-no-reply at lists.osmocom.org (arvind.sirsikar) Date: Fri, 30 Sep 2016 10:25:45 +0000 Subject: [PATCH] osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/861 to look at the new patch set (#4). EGPRS: add test case to show EPDAN BSN out of window bug This patch adds a test case test_egprs_tbf_epdan_out_of_rx_window, Which expects a current bug with EPDAN for Interpretation of the bitmap explained in section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that a bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored. But current PCU implementation drops the EPDAN and does not update status of the BSN which are inside the window. The test's expectation is corrected along with the bug fix in a subsequent commit. Related: OS#1789 Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 --- M tests/tbf/TbfTest.cpp M tests/tbf/TbfTest.err M tests/tbf/TbfTest.ok 3 files changed, 147 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/61/861/4 diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 3e17d8f..3ae9cbe 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -26,6 +26,7 @@ #include "pcu_utils.h" #include "gprs_bssgp_pcu.h" #include "pcu_l1_if.h" +#include "decoding.h" extern "C" { #include "pcu_vty.h" @@ -2017,6 +2018,113 @@ printf("=== end %s ===\n", __func__); } +/* + * This test simulates the section 9.1.8.2.4 of 44.060 + * version 7.27.0 Release 7. Which explains the Interpretation of the bitmap + * as a bit within the uncompressed bitmap whose BSN is not within the transmit + * window shall be ignored. Which fails because of existing bug. This test case + * expects the same bug. which shall be fixed in subsequent patch + */ +static void test_egprs_tbf_epdan_out_of_rx_window(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + int i; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + uint32_t fn = 2654167; /* 17,25,9 */ + uint8_t trx_no; + int num_blocks; + uint32_t tlli = 0xffeeddcc; + gprs_rlcmac_dl_tbf *dl_tbf; + int ts_no = 4; + bitvec *block; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + EGPRS_PD_AckNack_t *ack_nack; + RlcMacUplink_t ul_control_block; + gprs_rlc_v_b *prlcmvb; + gprs_rlc_dl_window *prlcdlwindow; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + /* ARQ II */ + bts->dl_arq_type = EGPRS_ARQ2; + + /* + * Over the Air message captured has been + * used to simulate this test case. During + * over the air testing, v_a was 1176, vs was 1288, + * max sns was 2048 + * and window size of 480. + */ + uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1, + 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f, + 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no); + dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + prlcdlwindow = &dl_tbf->m_window; + prlcmvb = &prlcdlwindow->m_v_b; + prlcdlwindow->m_v_s = 1288; + prlcdlwindow->m_v_a = 1176; + prlcdlwindow->set_sns(2048); + prlcdlwindow->set_ws(480); + prlcmvb->mark_unacked(1176); + prlcmvb->mark_unacked(1177); + prlcmvb->mark_unacked(1286); + prlcmvb->mark_unacked(1287); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + block = bitvec_alloc(23); + + bitvec_unpack(block, data_msg); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + decode_gsm_rlcmac_uplink(block, &ul_control_block); + + ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack; + + OSMO_ASSERT(prlcmvb->is_unacked(1176)); + OSMO_ASSERT(prlcmvb->is_unacked(1177)); + OSMO_ASSERT(prlcmvb->is_unacked(1286)); + OSMO_ASSERT(prlcmvb->is_unacked(1287)); + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &dl_tbf->m_window); + + dl_tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + /* + * TODO:status of BSN:1176,1177 shall be invalid + * status of BSN:1286,1287 shall be acked. + * both condition fails because of existing bug. Which shall be + * fixed in subsequent commit + */ + + OSMO_ASSERT(prlcmvb->is_unacked(1176)); + OSMO_ASSERT(prlcmvb->is_unacked(1177)); + OSMO_ASSERT(prlcmvb->is_unacked(1286)); + OSMO_ASSERT(prlcmvb->is_unacked(1287)); + + bitvec_free(block); + tbf_free(dl_tbf); + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_two_phase_spb(void) { BTS the_bts; @@ -2695,6 +2803,7 @@ test_tbf_puan_urbb_len(); test_tbf_update_ws(); test_tbf_li_decoding(); + test_egprs_tbf_epdan_out_of_rx_window(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0c9c877..877e0ad 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -6521,3 +6521,39 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI = 0x00000000, TA 220 -> 0 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK +- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF! +DL packet loss of IMSI= / TLLI=0xffeeddcc: 100% +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index eb870ea..efcfdee 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -66,3 +66,5 @@ === end test_tbf_update_ws === === start test_tbf_li_decoding === === end test_tbf_li_decoding === +=== start test_egprs_tbf_epdan_out_of_rx_window === +=== end test_egprs_tbf_epdan_out_of_rx_window === -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar From gerrit-no-reply at lists.osmocom.org Fri Sep 30 10:57:54 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 10:57:54 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move scheduling check inside repeat_last_sid In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/967 to look at the new patch set (#4). DTX: move scheduling check inside repeat_last_sid Note: this also require changes to properly link against libosmocodec. Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb --- M include/osmo-bts/msg_utils.h M src/common/Makefile.am M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/Makefile.am M src/osmo-bts-sysmo/tch.c M tests/misc/Makefile.am 7 files changed, 61 insertions(+), 79 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/67/967/4 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 456ff3c..f07623d 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -6,6 +6,8 @@ #include +#include + #include struct msgb; @@ -28,7 +30,5 @@ size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index fbb6572..856f741 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS) noinst_LIBRARIES = libbts.a libl1sched.a libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index ae2dd28..5c6bbbe 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -126,32 +126,13 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } -/* repeat last SID if possible, returns SID length + 1 or 0 */ -/*! \brief Repeat last SID if possible in case of DTX - * \param[in] lchan Logical channel on which we check scheduling - * \param[in] dst Buffer to copy last SID into - * \returns Number of bytes copied + 1 (to accommodate for extra byte with - * payload type) or 0 if there's nothing to copy - */ -uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) -{ - if (lchan->tch.last_sid.len) { - memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); - lchan->tch.last_sid.fn = fn; - return lchan->tch.last_sid.len + 1; - } - LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " - "is empty - sent nothing\n", - get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); - return 0; -} - /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, + uint32_t fn) { /* Compute approx. time delta based on Fn duration */ uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.last_sid.fn); @@ -183,7 +164,7 @@ * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) { /* According to 3GPP TS 45.008 ? 8.3: */ static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, @@ -198,6 +179,39 @@ return false; } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type), 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + /* FIXME: add EFR support */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) + return 0; + + if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { + if (dtx_sched_optional(lchan, fn)) + return 0; + } else + if (dtx_amr_sid_optional(lchan, fn)) + return 0; + + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + + LOGP(DL1C, LOGL_DEBUG, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + + return 0; +} + /** * Return 0 in case the IPA structure is okay and in this * case the l2h will be set to the beginning of the data. diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 2fd935e..46ad24c 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -442,6 +441,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -456,43 +456,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 34f4bb0..8e39a3a 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -29,7 +29,7 @@ misc/sysmobts_mgr_temp.c \ misc/sysmobts_mgr_calib.c \ eeprom.c -sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a +sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c eeprom.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 714570c..81cd791 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -544,6 +543,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -558,43 +558,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am index f60325b..d5acb18 100644 --- a/tests/misc/Makefile.am +++ b/tests/misc/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) noinst_PROGRAMS = misc_test EXTRA_DIST = misc_test.ok -- To view, visit https://gerrit.osmocom.org/967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 11:15:19 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 11:15:19 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#7). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 92 insertions(+), 70 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/7 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 5c6bbbe..7248a4e 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,55 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; /* only needed for old sysmo firmware */ + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + /* SID_UPDATE (sti == 1) should be cached and send later, + SID_FIRST (sti == 0) - cached and send right away */ + return sti ? -EAGAIN : 0; + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..08c64ab 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..3eb9bfd 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 7 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:30:38 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:30:38 +0000 Subject: osmo-bts[master]: LC15: Clarify msgb ownership / fix memory leaks In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/981 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:31:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:31:46 +0000 Subject: libosmocore[master]: Mark inline header function as static In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/966 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib751f7467d54cbcae76f72448a38e30f2ecc63d4 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:31:51 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:31:51 +0000 Subject: [MERGED] libosmocore[master]: Mark inline header function as static In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Mark inline header function as static ...................................................................... Mark inline header function as static Change-Id: Ib751f7467d54cbcae76f72448a38e30f2ecc63d4 --- M include/osmocom/codec/codec.h 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index 74eca46..fb127b5 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -46,7 +46,7 @@ * \param[in] ft AMR Frame Type * \returns true if AMR with given Frame Type contains voice, false otherwise */ -inline bool osmo_amr_is_speech(enum osmo_amr_type ft) +static inline bool osmo_amr_is_speech(enum osmo_amr_type ft) { switch (ft) { case AMR_4_75: -- To view, visit https://gerrit.osmocom.org/966 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib751f7467d54cbcae76f72448a38e30f2ecc63d4 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:32:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:32:00 +0000 Subject: [MERGED] osmo-bts[master]: LC15: Clarify msgb ownership / fix memory leaks In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: LC15: Clarify msgb ownership / fix memory leaks ...................................................................... LC15: Clarify msgb ownership / fix memory leaks This is similar to 21b020b33633683d7c785af15c773aab0f79d0de which changes the way msgb is allocated/freed in sysmobts. Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087 --- M src/osmo-bts-litecell15/l1_if.c 1 file changed, 31 insertions(+), 22 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index 0779dac..cf7ce58 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -399,6 +399,7 @@ LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d " "chan_nr %d link_id %d\n", l1sap->oph.primitive, l1sap->oph.operation, chan_nr, link_id); + msgb_free(l1msg); return -EINVAL; } @@ -421,13 +422,10 @@ empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } - /* free the msgb holding the L1SAP primitive */ - msgb_free(msg); - /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) { LOGP(DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); - msgb_free(msg); + msgb_free(l1msg); } return 0; @@ -509,8 +507,6 @@ return ph_tch_req(trx, l1sap->oph.msg, l1sap); } - if (msg) - msgb_free(msg); return 0; } @@ -554,7 +550,6 @@ l1if_rsl_deact_sacch(lchan); else l1if_rsl_chan_rel(lchan); - msgb_free(msg); break; default: LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", @@ -571,6 +566,8 @@ struct msgb *msg = l1sap->oph.msg; int rc = 0; + /* called functions MUST NOT take ownership of msgb, as it is + * free()d below */ switch (OSMO_PRIM_HDR(&l1sap->oph)) { case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): rc = ph_data_req(trx, msg, l1sap); @@ -587,13 +584,14 @@ rc = -EINVAL; } - if (rc) - msgb_free(msg); + msgb_free(msg); + return rc; } static int handle_mph_time_ind(struct lc15l1_hdl *fl1, - GsmL1_MphTimeInd_t *time_ind) + GsmL1_MphTimeInd_t *time_ind, + struct msgb *msg) { struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1); struct gsm_bts *bts = trx->bts; @@ -615,6 +613,8 @@ PRIM_OP_INDICATION, NULL); l1sap.u.info.type = PRIM_INFO_TIME; l1sap.u.info.u.time_ind.fn = fn; + + msgb_free(msg); return l1sap_up(trx, &l1sap); } @@ -758,6 +758,8 @@ link_id = 0x40; else link_id = 0; + /* recycle the msgb and use it for the L1 primitive, + * which means that we (or our caller) must not free it */ rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive\n"); @@ -824,6 +826,8 @@ msgb_free(resp_msg); } + /* free the msgb, as we have not handed it to l1sap and thus + * need to release its memory */ msgb_free(l1p_msg); return 0; @@ -854,6 +858,8 @@ l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 100); l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1); + /* l1sap wants to take msgb ownership. However, as there is no + * msg, it will msgb_free(l1sap.oph.msg == NULL) */ return l1sap_up(trx, &l1sap); } @@ -999,29 +1005,28 @@ GsmL1_Prim_t *l1p = msgb_l1prim(msg); int rc = 0; + /* all the below called functions must take ownership of the msgb */ switch (l1p->id) { case GsmL1_PrimId_MphTimeInd: - rc = handle_mph_time_ind(fl1, &l1p->u.mphTimeInd); + rc = handle_mph_time_ind(fl1, &l1p->u.mphTimeInd, msg); break; case GsmL1_PrimId_MphSyncInd: break; case GsmL1_PrimId_PhConnectInd: break; case GsmL1_PrimId_PhReadyToSendInd: - return handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, + rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, msg); + break; case GsmL1_PrimId_PhDataInd: - return handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); + rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); + break; case GsmL1_PrimId_PhRaInd: - return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); + rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); break; default: break; } - - /* Special return value '1' means: do not free */ - if (rc != 1) - msgb_free(msg); return rc; } @@ -1056,10 +1061,12 @@ llist_for_each_entry(wlc, &fl1h->wlc_list, list) { if (is_prim_compat(l1p, wlc)) { llist_del(&wlc->list); - if (wlc->cb) + if (wlc->cb) { + /* call-back function must take + * ownership of msgb */ rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg, wlc->cb_data); - else { + } else { rc = 0; msgb_free(msg); } @@ -1087,10 +1094,12 @@ * sending the same primitive */ if (wlc->is_sys_prim && sysp->id == wlc->conf_prim_id) { llist_del(&wlc->list); - if (wlc->cb) + if (wlc->cb) { + /* call-back function must take + * ownership of msgb */ rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg, wlc->cb_data); - else { + } else { rc = 0; msgb_free(msg); } -- To view, visit https://gerrit.osmocom.org/981 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:32:57 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:32:57 +0000 Subject: osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Patch Set 11: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 11 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:33:46 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:33:46 +0000 Subject: osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 7 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:35:01 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:35:01 +0000 Subject: osmo-bts[master]: DTX: move scheduling check inside repeat_last_sid In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/967/4//COMMIT_MSG Commit Message: Line 9: Note: this also require changes to properly link against libosmocodec. please clearly state the commit or even better Change-Id that this depends on -- To view, visit https://gerrit.osmocom.org/967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:35:39 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:35:39 +0000 Subject: osmo-bts[master]: DTX: further SID caching fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:35:56 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:35:56 +0000 Subject: openbsc[master]: log CTRL bind only once In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/980 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1a874efe365a1ecf8ec37b058215b95b9a635ec2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:35:59 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:35:59 +0000 Subject: [MERGED] openbsc[master]: log CTRL bind only once In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: log CTRL bind only once ...................................................................... log CTRL bind only once After libosmocore 38d232ee5d2ceb045d9ad6d3a23afcb4972523f7 which outputs 'CTRL at ' from ctrl_interface_setup_dynip(), there's no need to log the CTRL bind here anymore. Change-Id: I1a874efe365a1ecf8ec37b058215b95b9a635ec2 --- M openbsc/src/gprs/sgsn_main.c M openbsc/src/osmo-bsc/osmo_bsc_main.c M openbsc/src/osmo-bsc_nat/bsc_nat.c M openbsc/src/osmo-nitb/bsc_hack.c 4 files changed, 0 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 93848f5..822c359 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -389,8 +389,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DGPRS, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_SGSN); ctrl = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_SGSN); if (!ctrl) { diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 2ee5fb4..d3128e4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -229,8 +229,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); bsc_gsmnet->ctrl = bsc_controlif_setup(bsc_gsmnet, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 57cc8b3..6ae8c05 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1669,8 +1669,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNAT, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BSC_NAT); nat->ctrl = bsc_nat_controlif_setup(nat, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BSC_NAT); if (!nat->ctrl) { diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index 8e1ddae..28dbb6f 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -313,8 +313,6 @@ /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - LOGP(DNM, LOGL_NOTICE, "CTRL at %s %d\n", - ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); bsc_gsmnet->ctrl = bsc_controlif_setup(bsc_gsmnet, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_NITB_BSC); -- To view, visit https://gerrit.osmocom.org/980 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1a874efe365a1ecf8ec37b058215b95b9a635ec2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:36:31 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:36:31 +0000 Subject: libosmocore[master]: configure: add --enable-sanitize, use in jenkins.sh In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idf7f46fa048608c2951f2473cb528f6c8dc2681d Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:41:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:41:19 +0000 Subject: openbsc[master]: OML: Fixing static OML attribute tables In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 Rather than hand-encoding the message, I was originally more hoping for passing asomething like a tlvp_parsed structure into an encoder, which then builds the respective message by calling one generic function that puts together all the IEs. But well, the important part is to fix the current bug, so let's not over-complicate things and keep the approach you implemented. However, what we must do is to verify such a change. In order to do so, we should * generate the respective OML messages using the old code * capture the binary (e.g. with wireshark, or by hexdumping it) * write a test case using that binary data, testing the old implementation * change the implementation, run the old test case[s] with the old binary data against the new implementation, to verify it still generates identical binary data as before. -- To view, visit https://gerrit.osmocom.org/973 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibeb34a84912d6cf695f553a34c69320fca7d08fa Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:06 +0000 Subject: openbsc[master]: vty_test_runner.py: make unittest print all output by default In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/971 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:18 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:18 +0000 Subject: openbsc[master]: vty_test_runner.py: fix indents to use spaces, fix vim comment In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/972 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:20 +0000 Subject: [MERGED] openbsc[master]: vty_test_runner.py: fix indents to use spaces, fix vim comment In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: vty_test_runner.py: fix indents to use spaces, fix vim comment ...................................................................... vty_test_runner.py: fix indents to use spaces, fix vim comment Most of this file uses four spaces of indenting. Replace all tabs with spaces. Remove the erratic 'set' from the recently added vim comment at the bottom. Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf --- M openbsc/tests/vty_test_runner.py 1 file changed, 26 insertions(+), 26 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 8dc4f70..a73dadd 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -65,38 +65,38 @@ return (4243, "./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp") def testForcePtime(self): - self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' rtp force-ptime 20\r') > 0) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.enable() + res = self.vty.command("show running-config") + self.assert_(res.find(' rtp force-ptime 20\r') > 0) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no rtp force-ptime") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) - self.assertEquals(res.find(' no rtp force-ptime\r'), -1) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no rtp force-ptime") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp force-ptime 20\r'), -1) + self.assertEquals(res.find(' no rtp force-ptime\r'), -1) def testOmitAudio(self): self.vty.enable() - res = self.vty.command("show running-config") - self.assert_(res.find(' sdp audio-payload send-name\r') > 0) - self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) + res = self.vty.command("show running-config") + self.assert_(res.find(' sdp audio-payload send-name\r') > 0) + self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1) - self.vty.command("configure terminal") - self.vty.command("mgcp") - self.vty.command("no sdp audio-payload send-name") - res = self.vty.command("show running-config") - self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) - self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) + self.vty.command("configure terminal") + self.vty.command("mgcp") + self.vty.command("no sdp audio-payload send-name") + res = self.vty.command("show running-config") + self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1) + self.assert_(res.find(' no sdp audio-payload send-name\r') > 0) # TODO: test it for the trunk! def testBindAddr(self): self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("mgcp") + self.vty.command("configure terminal") + self.vty.command("mgcp") # enable.. disable bts-bind-ip self.vty.command("rtp bts-bind-ip 254.253.252.250") @@ -540,7 +540,7 @@ res = self.vty.command("write terminal") self.assert_(res.find('meas-feed scenario bla') > 0) - self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") + self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") res = self.vty.command("write terminal") self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890'), -1) self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz012345'), -1) @@ -733,7 +733,7 @@ self.assertEquals(res.find("core-location-area-code"), -1) self.assertEquals(res.find("core-cell-identity"), -1) - self.vty.command("configure terminal") + self.vty.command("configure terminal") self.vty.command("msc 0") self.vty.command("core-location-area-code 666") self.vty.command("core-cell-identity 333") @@ -1256,8 +1256,8 @@ continue if not conn: - raise Exception("VTY reports MSC is connected, but I haven't" - " connected yet: %r %r" % (ip, port)) + raise Exception("VTY reports MSC is connected, but I haven't" + " connected yet: %r %r" % (ip, port)) return conn def ipa_handle_small(x, verbose = False): @@ -1360,4 +1360,4 @@ res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) -# vim: set shiftwidth=4 expandtab nocin ai +# vim: shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/972 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4273b3314defb1e5b31b509c2ac7d7c6cd6834cf Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:21 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:21 +0000 Subject: [MERGED] openbsc[master]: vty_test_runner.py: make unittest print all output by default In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: vty_test_runner.py: make unittest print all output by default ...................................................................... vty_test_runner.py: make unittest print all output by default Add option to TextTestRunner that shows print output on stdout. It's better to see everything in our jenkins runs and not hide test output. Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 --- M openbsc/tests/vty_test_runner.py 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 5bb27a8..8dc4f70 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -1357,7 +1357,7 @@ add_nat_test(suite, workdir) add_gbproxy_test(suite, workdir) add_sgsn_test(suite, workdir) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) + res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite) sys.exit(len(res.errors) + len(res.failures)) # vim: set shiftwidth=4 expandtab nocin ai -- To view, visit https://gerrit.osmocom.org/971 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If4be1ad1c81c9ed4ab9b208b4c6d1e4b2cc8fdd5 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:47 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:47 +0000 Subject: openbsc[master]: SGSN: Fixing build config In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/963 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6921e6198ea7f99fe5276f91cbc522091853bc4e Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:42:48 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:42:48 +0000 Subject: [MERGED] openbsc[master]: SGSN: Fixing build config In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SGSN: Fixing build config ...................................................................... SGSN: Fixing build config Tests for V.42bis, slhc, llc-xid and sndcp-xid are built and executed on all build configurations, but are only needed when the sgsn (gprs) is built. This patch adds conditions check if the tests mentioned abvove are needed or not. Change-Id: I6921e6198ea7f99fe5276f91cbc522091853bc4e --- M openbsc/tests/Makefile.am M openbsc/tests/testsuite.at 2 files changed, 8 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index 0ebd2e2..468edd2 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -9,10 +9,6 @@ trau \ subscr \ mm_auth \ - xid \ - sndcp_xid \ - slhc \ - v42bis \ $(NULL) if BUILD_NAT @@ -40,6 +36,10 @@ SUBDIRS += \ sgsn \ oap \ + xid \ + sndcp_xid \ + slhc \ + v42bis \ $(NULL) endif endif diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index f18b734..4905cd1 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -126,24 +126,28 @@ AT_SETUP([xid]) AT_KEYWORDS([xid]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/xid/xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([sndcp_xid]) AT_KEYWORDS([sndcp_xid]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([slhc]) AT_KEYWORDS([slhc]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/slhc/slhc_test.ok > expout AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) AT_CLEANUP AT_SETUP([v42bis]) AT_KEYWORDS([v42bis]) +AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) cat $abs_srcdir/v42bis/v42bis_test.ok > expout AT_CHECK([$abs_top_builddir/tests/v42bis/v42bis_test], [], [expout], [ignore]) AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/963 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6921e6198ea7f99fe5276f91cbc522091853bc4e Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:55:57 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:55:57 +0000 Subject: openbsc[master]: sndcp: Fixups for sndcp layer based on coverity-scan suggest... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/965/1/openbsc/src/gprs/gprs_sndcp.c File openbsc/src/gprs/gprs_sndcp.c: Line 44: #define DEBUG_IP_PACKETS 1 /* 0=Disabled, 1=Enabled */ why do we enable debugging in this patch? Is debugging required for regular operation? This shouldn't be the case. And if it's not a fix, it shouldn't be part of the patch. -- To view, visit https://gerrit.osmocom.org/965 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4f9adf251f5119e67ffe76baad6f1f996ac8dbad Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:58:20 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:58:20 +0000 Subject: osmo-bts[master]: rsl: improved log output improving the log output In-Reply-To: References: Message-ID: Patch Set 3: Code-Review-2 (1 comment) https://gerrit.osmocom.org/#/c/902/3/src/common/rsl.c File src/common/rsl.c: Line 1602: speech_mode = TLVP_VAL(&tp, RSL_IE_IPAC_SPEECH_MODE); the comment doesn't match the code. As the comment suggests, anyof those information elements can not be present in the message, as they are optional IEs. The existing code *should* deal with that. The new code unconditionally introduces logging code that de-references the pointers, which might be NULL -> boom. -- To view, visit https://gerrit.osmocom.org/902 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 12:59:19 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 12:59:19 +0000 Subject: [PATCH] osmo-bts[master]: octphy: set tx attenuation via VTY In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/905 to look at the new patch set (#5). octphy: set tx attenuation via VTY add code to configure the transmision power via VTY Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 --- M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c M src/osmo-bts-octphy/octphy_vty.c 3 files changed, 29 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/05/905/5 diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index ea0fb33..7c09b2d 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -62,6 +62,7 @@ /* configuration */ uint32_t rf_port_index; uint32_t rx_gain_db; + uint32_t tx_atten_flag; uint32_t tx_atten_db; struct octphy_hdl *hdl; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 7735261..b3d800a 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1349,7 +1349,13 @@ oc->Config.usBcchArfcn = trx->bts->c0->arfcn; oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; /* FIXME: compute this based on nominal transmit power, etc. */ - oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + if (plink->u.octphy.tx_atten_flag == 1) { + oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; + } else { + /* Take the Tx Attn received in set radio attribures + * x4 is for the value in db */ + oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; + } LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "tsc=%u, rx_gain=%u, tx_atten=%u)\n", diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index 3ea576c..53099c8 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -135,6 +135,24 @@ return CMD_SUCCESS; } +DEFUN(cfg_phy_tx_atten_flag, cfg_phy_tx_atten_flag_cmd, + "octphy tx-attenuation-flag <0-1>", + OCT_STR "1 - Use config file to set Tx Attenuation\n" + "Use config file to set Tx Attenuation\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.tx_atten_flag = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_phy_tx_atten_db, cfg_phy_tx_atten_db_cmd, "octphy tx-attenuation <0-359>", OCT_STR "Configure the Tx Attenuation in quarter-dB\n" @@ -202,6 +220,8 @@ VTY_NEWLINE); vty_out(vty, " rx-gain %u%s", plink->u.octphy.rx_gain_db, VTY_NEWLINE); + vty_out(vty, " tx-attenuation-flag %u%s", plink->u.octphy.tx_atten_flag, + VTY_NEWLINE); vty_out(vty, " tx-attenuation %u%s", plink->u.octphy.tx_atten_db, VTY_NEWLINE); vty_out(vty, " rf-port-index %u%s", plink->u.octphy.rf_port_index, @@ -250,6 +270,7 @@ install_element(PHY_NODE, &cfg_phy_netdev_cmd); install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); + install_element(PHY_NODE, &cfg_phy_tx_atten_flag_cmd); install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); install_element_ve(&show_rf_port_stats_cmd); -- To view, visit https://gerrit.osmocom.org/905 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:03:18 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 13:03:18 +0000 Subject: osmo-bts[master]: octphy: set tx attenuation via VTY In-Reply-To: References: Message-ID: Patch Set 5: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/905/5/src/osmo-bts-octphy/octphy_vty.c File src/osmo-bts-octphy/octphy_vty.c: Line 139: "octphy tx-attenuation-flag <0-1>", I think the syntax and description should be more explicit. Nobody knows what a "tx attenuation flag is". The help message is also not helpful. In reality, this configures whether the OML Attribute or the config file should be used for configuring the Tx attenuation in the hardware. So something like "octphy tx-attenuation (oml|config-file)" would probably be more easily understood, particularly with more descriptive help message. As we alreday have the "octphy tx-attenuation" below, it might even make more sense to simply change that to "octphy tx-attenuation (oml|<0-359>)" so with a single command one can either state that the OML value is to be used, or that an absolute value is specified. Much better, I think. -- To view, visit https://gerrit.osmocom.org/905 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:06:00 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 13:06:00 +0000 Subject: libosmo-abis[master]: Remove use of private oRTP function In-Reply-To: References: Message-ID: Patch Set 1: > I think this should be rised with upstream than - using private API > might work for now but it can be changed at any time without > notification which would lead to hard-to-find bugs. There's nothing to be raised with upstream, I think. You want to remove access to a private API, and I agree we should try that. However, then remove the select() based RTCP code completely and rely on polling, and verify that it all still works. If it does, we can marge such a patch [but not the current one]. Only if it doensn't we indeed should talk to upstream. -- To view, visit https://gerrit.osmocom.org/908 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:06:06 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 13:06:06 +0000 Subject: libosmo-abis[master]: Remove use of private oRTP function In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/908 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff1b15c68efca3e02267e0308142c6a7a0c2a974 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:49:50 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 13:49:50 +0000 Subject: [PATCH] osmo-bts[master]: DTX: further AMR SID cache fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/960 to look at the new patch set (#4). DTX: further AMR SID cache fixes (lc15, sysmo) * consolidate AMR CMR and CMI handling in common/amr.c * use it in save_last_sid() * remove dead code * properly compute RTP payload length for AMR * use save_last_sid() for FR & HR as well * invalidate cached SID if SPEECH frame is received Fixes: OS #1800, #1801 Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed --- M include/osmo-bts/amr.h M include/osmo-bts/msg_utils.h M src/common/amr.c M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 6 files changed, 129 insertions(+), 173 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/60/960/4 diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index 6bdc41f..f313287 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -11,7 +11,8 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, const uint8_t *mr_conf, unsigned int len); -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi); +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f03eb43..456ff3c 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -24,8 +24,9 @@ }; void lchan_set_marker(bool t, struct gsm_lchan *lchan); -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); diff --git a/src/common/amr.c b/src/common/amr.c index 56ed430..b5d2c37 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -22,7 +22,8 @@ LOGPC(ss, logl, "\n"); } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) +static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) { unsigned int i; for (i = 0; i < amr_mrc->num_modes; i++) { @@ -32,6 +33,46 @@ return -EINVAL; } +static inline uint8_t set_cmr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmr) +{ + int rc; + + /* Codec Mode Request is in upper 4 bits of RTP payload header, + * and we simply copy the CMR into the CMC */ + if (cmr == 0xF) { + /* FIXME: we need some state about the last codec mode */ + return 0; + } + + rc = get_amr_mode_idx(amr_mrc, cmr); + if (rc < 0) { + /* FIXME: we need some state about the last codec mode */ + LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); + return 0; + } + return rc; +} + +static inline uint8_t set_cmi_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) +{ + int rc = get_amr_mode_idx(amr_mrc, cmi); + if (rc < 0) { + LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", + cmi); + return 0; + } + return rc; +} + +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr) +{ + data[0] = set_cmi_mode_idx(amr_mrc, cmi); + data[1] = set_cmr_mode_idx(amr_mrc, cmr); +} + /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more * comfortable internal data structure */ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 967b10d..ae2dd28 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -99,17 +100,30 @@ } /* store the last SID frame in lchan context */ -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) +/*! \brief Store the last SID frame in lchan context + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] l1_payload buffer with SID data + * \param[in] length length of l1_payload + * \param[in] fn Frame Number for which we check scheduling + * \param[in] update 0 if SID_FIRST, 1 if SID_UPDATE, -1 if not AMR SID + * \param[in] cmr Codec Mode Request (AMR-specific, ignored otherwise) + * \param[in] cmi Codec Mode Indication (AMR-specific, ignored otherwise) + */ +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi) { - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); + size_t amr = (update < 0) ? 0 : 2, + copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; + lchan->tch.last_sid.len = copy_len + amr; lchan->tch.last_sid.fn = fn; lchan->tch.last_sid.is_update = update; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); + if (amr) + amr_set_mode_pref(lchan->tch.last_sid.buf, &lchan->tch.amr_mr, + cmi, cmr); + memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } /* repeat last SID if possible, returns SID length + 1 or 0 */ diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index bcf981e..2fd935e 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -200,85 +200,12 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); memcpy(l1_payload+2, rtp_payload, payload_len); + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -305,6 +232,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -318,32 +246,54 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index f350398..714570c 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -283,19 +283,8 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - #ifdef USE_L1_RTP_MODE memcpy(l1_payload+2, rtp_payload, payload_len); #else @@ -310,72 +299,9 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -402,6 +328,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -415,34 +342,56 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; #endif case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi); } break; default: -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:49:50 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 13:49:50 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move scheduling check inside repeat_last_sid In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/967 to look at the new patch set (#5). DTX: move scheduling check inside repeat_last_sid Note: this also require changes to properly link against libosmocodec - see 2bb65be159dfdabf664fec569b343320301701b0 in libosmocore. Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb --- M include/osmo-bts/msg_utils.h M src/common/Makefile.am M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/Makefile.am M src/osmo-bts-sysmo/tch.c M tests/misc/Makefile.am 7 files changed, 61 insertions(+), 79 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/67/967/5 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 456ff3c..f07623d 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -6,6 +6,8 @@ #include +#include + #include struct msgb; @@ -28,7 +30,5 @@ size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn); -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index fbb6572..856f741 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS) noinst_LIBRARIES = libbts.a libl1sched.a libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index ae2dd28..5c6bbbe 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -126,32 +126,13 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } -/* repeat last SID if possible, returns SID length + 1 or 0 */ -/*! \brief Repeat last SID if possible in case of DTX - * \param[in] lchan Logical channel on which we check scheduling - * \param[in] dst Buffer to copy last SID into - * \returns Number of bytes copied + 1 (to accommodate for extra byte with - * payload type) or 0 if there's nothing to copy - */ -uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) -{ - if (lchan->tch.last_sid.len) { - memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); - lchan->tch.last_sid.fn = fn; - return lchan->tch.last_sid.len + 1; - } - LOGP(DL1C, LOGL_NOTICE, "Have to send %s frame on TCH but SID buffer " - "is empty - sent nothing\n", - get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); - return 0; -} - /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_amr_sid_optional(const struct gsm_lchan *lchan, + uint32_t fn) { /* Compute approx. time delta based on Fn duration */ uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.last_sid.fn); @@ -183,7 +164,7 @@ * \param[in] fn Frame Number for which we check scheduling * \returns true if transmission can be omitted, false otherwise */ -bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) +static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) { /* According to 3GPP TS 45.008 ? 8.3: */ static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, @@ -198,6 +179,39 @@ return false; } +/* repeat last SID if possible, returns SID length + 1 or 0 */ +/*! \brief Repeat last SID if possible in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] dst Buffer to copy last SID into + * \returns Number of bytes copied + 1 (to accommodate for extra byte with + * payload type), 0 if there's nothing to copy + */ +uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) +{ + /* FIXME: add EFR support */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) + return 0; + + if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { + if (dtx_sched_optional(lchan, fn)) + return 0; + } else + if (dtx_amr_sid_optional(lchan, fn)) + return 0; + + if (lchan->tch.last_sid.len) { + memcpy(dst, lchan->tch.last_sid.buf, lchan->tch.last_sid.len); + lchan->tch.last_sid.fn = fn; + return lchan->tch.last_sid.len + 1; + } + + LOGP(DL1C, LOGL_DEBUG, "Have to send %s frame on TCH but SID buffer " + "is empty - sent nothing\n", + get_value_string(gsm48_chan_mode_names, lchan->tch_mode)); + + return 0; +} + /** * Return 0 in case the IPA structure is okay and in this * case the l2h will be set to the beginning of the data. diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 2fd935e..46ad24c 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -442,6 +441,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -456,43 +456,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 34f4bb0..8e39a3a 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -29,7 +29,7 @@ misc/sysmobts_mgr_temp.c \ misc/sysmobts_mgr_calib.c \ eeprom.c -sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a +sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c eeprom.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 714570c..81cd791 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -544,6 +543,7 @@ GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; + int rc; msg = l1p_msgb_alloc(); if (!msg) @@ -558,43 +558,27 @@ switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_AMR: *payload_type = GsmL1_TchPlType_Amr; - if (dtx_amr_sid_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA, AMR_GOOD); break; case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) *payload_type = GsmL1_TchPlType_Fr; else *payload_type = GsmL1_TchPlType_Hr; - /* unlike AMR, FR & HR schedued based on absolute FN value */ - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; - if (dtx_sched_optional(lchan, fn)) { - msgb_free(msg); - return NULL; - } - msu_param->u8Size = repeat_last_sid(lchan, l1_payload, fn); - if (!msu_param->u8Size) - return NULL; break; default: msgb_free(msg); - msg = NULL; - break; + return NULL; } + rc = repeat_last_sid(lchan, l1_payload, fn); + if (!rc) { + msgb_free(msg); + return NULL; + } + msu_param->u8Size = rc; + return msg; } diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am index f60325b..d5acb18 100644 --- a/tests/misc/Makefile.am +++ b/tests/misc/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) noinst_PROGRAMS = misc_test EXTRA_DIST = misc_test.ok -- To view, visit https://gerrit.osmocom.org/967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 13:49:50 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 13:49:50 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#8). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 96 insertions(+), 70 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/8 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 5c6bbbe..99a211f 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; /* only needed for old sysmo firmware */ + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST - cached and send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, + cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + } + + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..bcb1edd 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..9be8659 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:27:37 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 14:27:37 +0000 Subject: [PATCH] osmo-pcu[master]: build: add -Wall Message-ID: Review at https://gerrit.osmocom.org/982 build: add -Wall I noticed that unused variables are not complained about by the build. Let's add -Wall. I also noticed that the Makefile.ams include STD_DEFINES_AND_INCLUDES, which is never set in configure.ac, so using that to add -Wall to all build contexts. Change-Id: I16711cf5a1ef8bd611074b3dd486ed7a0ae9df64 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/82/982/1 diff --git a/configure.ac b/configure.ac index d8fe719..bde15f6 100644 --- a/configure.ac +++ b/configure.ac @@ -69,6 +69,9 @@ AC_MSG_RESULT([$enable_vty_tests]) AM_CONDITIONAL(ENABLE_VTY_TESTS, test "x$enable_vty_tests" = "xyes") +STD_DEFINES_AND_INCLUDES="-Wall" +AC_SUBST(STD_DEFINES_AND_INCLUDES) + AC_OUTPUT( src/Makefile examples/Makefile -- To view, visit https://gerrit.osmocom.org/982 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I16711cf5a1ef8bd611074b3dd486ed7a0ae9df64 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:34:07 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 14:34:07 +0000 Subject: osmo-pcu[master]: EGPRS: add test case to show EPDAN BSN out of window bug In-Reply-To: References: Message-ID: Patch Set 4: Code-Review-1 (9 comments) getting there... https://gerrit.osmocom.org/#/c/861/4//COMMIT_MSG Commit Message: Line 10: Which expects a current bug with EPDAN for Interpretation of the (lower case after comma, also for 'interpretation') https://gerrit.osmocom.org/#/c/861/4/tests/tbf/TbfTest.cpp File tests/tbf/TbfTest.cpp: Line 2032: int i; drop unused 'i' Line 2035: uint32_t fn = 2654167; /* 17,25,9 */ drop unused 'fn' Line 2061: * Over the Air message captured has been A test case is not simulated, it is run and by that simulates a real situation :) "Simulate a message captured during over-the-air testing, where the following values were observed: v_a = 1176, vs = 1288, max sns = 2048, window size = 480." Line 2072: dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no); interesting, there was an error here passing 'the_bts' instead of '&the_bts' which I didn't spot before. Line 2074: prlcdlwindow = &dl_tbf->m_window; single space please Line 2106: &bsn_begin, &bsn_end, &dl_tbf->m_window); You're not using num_blocks. Either remove it, or, rather, assert that it has the expected value. Line 2116: */ A blank line above this comment, no blank line below. Again, use a period '.' when a sentence ends, and start a new sentence with upper case. Instead of 'both condition...' please say 'Below assertions show a bug, and shall be adjusted along with the fix in a subsequent commit.' Line 2806: test_egprs_tbf_epdan_out_of_rx_window(); the naming above used the ordering 'test_tbf_egprs_*', so stick with that -- To view, visit https://gerrit.osmocom.org/861 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32b67f5c05707155281128b776a90a1e3d587b2 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:38:20 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 14:38:20 +0000 Subject: osmo-pcu[master]: EGPRS: fix for EPDAN out of window In-Reply-To: References: Message-ID: Patch Set 4: (3 comments) https://gerrit.osmocom.org/#/c/862/4//COMMIT_MSG Commit Message: Line 16: the remaining bits. much better, thanks :) https://gerrit.osmocom.org/#/c/862/2/src/rlc.cpp File src/rlc.cpp: Line 108: unsigned num_blocks = rbb->cur_bit > (unsigned)distance() > The distance is supposed to be positive. But earlier return type is signed. It is not enough that it is supposed to be positive, it must be *guaranteed* to be positive, or this cast will blow up in our faces. https://gerrit.osmocom.org/#/c/862/4/src/tbf_dl.cpp File src/tbf_dl.cpp: Line 939: I've tried for some minutes to understand, but I don't see it yet... why can this if() block be removed? The calculations removed here are somewhat different than the simpler num_blocks calculation added above, could you please help me to match them up? -- To view, visit https://gerrit.osmocom.org/862 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6 Gerrit-PatchSet: 4 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:51:30 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 14:51:30 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#13). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 32 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/13 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index cf7ce58..a4378c1 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -441,6 +441,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -464,17 +465,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -502,7 +506,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index bcb1edd..e246ffb 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..09627af 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,17 +460,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -497,7 +501,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 9be8659..ca9045e 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 13 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:51:30 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 14:51:30 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#9). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 96 insertions(+), 70 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/9 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 5c6bbbe..99a211f 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; /* only needed for old sysmo firmware */ + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST - cached and send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, + cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + } + + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..bcb1edd 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..9be8659 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 9 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:58:02 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 14:58:02 +0000 Subject: osmo-bts[master]: DTX: move scheduling check inside repeat_last_sid In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:58:17 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 14:58:17 +0000 Subject: osmo-bts[master]: DTX: further AMR SID cache fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 14:58:42 2016 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 30 Sep 2016 14:58:42 +0000 Subject: osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Patch Set 9: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 9 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 15:02:17 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 15:02:17 +0000 Subject: osmo-pcu[master]: Fix: DL slot allocation based on direction configured In-Reply-To: References: Message-ID: Patch Set 6: Code-Review-1 (6 comments) Disclaimer: I think the higher level discussion with Holger still needs to be resolved, I am focusing on the implementation details instead. https://gerrit.osmocom.org/#/c/819/6//COMMIT_MSG Commit Message: Line 12: Since 2nd DL TBF has less DL slot compared to 2nd TBF, 'less DL slots' with 's' Line 13: There is a difference in throughput between lower case after comma Line 18: Also mention here that maximise_direction is chosen to be an enum to be open for later additions. https://gerrit.osmocom.org/#/c/819/6/src/gprs_rlcmac_ts_alloc.cpp File src/gprs_rlcmac_ts_alloc.cpp: Line 782: break; indent break; with one more tab, see all other osmo code. https://gerrit.osmocom.org/#/c/819/6/src/pcu_vty.c File src/pcu_vty.c: Line 500: #define MAXIMISE_STR "Maximise direction based on configuration\n" I *still* don't like the 'based on configuration'. Everything in the VTY is based on configuration. Describe the direction of *what* is being maximised. After all, you can't maximise a direction per se, you maximise flow in a certain direction -- flow of what? Line 502: DEFUN(cfg_pcu_ts_alloc_maximise, usually, the naming here corresponds to the node and the VTY command, so I'd name this 'cfg_pcu_maximise_direction*', same as you have done for the 'no maximise-direction' below. -- To view, visit https://gerrit.osmocom.org/819 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4b4a99194ccae68bb3417bce538d16e944d5ec71 Gerrit-PatchSet: 6 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: arvind.sirsikar Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 15:58:45 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 15:58:45 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 25: (25 comments) https://gerrit.osmocom.org/#/c/416/25/src/decoding.cpp File src/decoding.cpp: Line 697: LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exists, " Actually ... what do you mean by 'exists'? Is received? https://gerrit.osmocom.org/#/c/416/25/src/egprs_rlc_compression.cpp File src/egprs_rlc_compression.cpp: Line 22: extern const char *zero_run_len_code_list[EGPRS_CODEWORDS]; the two arrays are not extern but defined further below. Line 37: /* The function expands the given tree by incorporating Still no need to state that it is a function! For example: 'Expand the given tree...' Line 40: * \param cdwd[in] Code word plural, and indicate the length: 'Array of code words, length must be EGPRS_CODEWORDS' Line 74: (remove space from the blank line) Line 248: * \param rlen[out] Caluculate run length fix typo. As I said before, it should say 'Calculated', not 'Calculate' (which would mean something else entirely). Line 267: dir = ((bmbuf[BITS_TO_BYTES(bit_pos) - 1] Come on, in BITS_TO_BYTES you '+1' and here you '-1' again? Since this is the only place using that define, that amounts to pure code bloat. This also completely invalidates your previous comment on the calculation. Drop the define entirely and just do / 8 here. Line 268: >> (7 - MOD8(bit_pos))) & 0x01); Drop outermost braces. Line 271: if (((dir&0x01) == 0) && (iter->left != NULL)) dir is already & 0x01 above. Since dir is boolean, no need to == 0: 'if (!dir && (iter...' Line 273: else if (((dir&0x01) == 1) && (iter->right != NULL)) 'if (dir && (iter...' Line 279: (*rlen) = (iter->run_length); drop all braces Line 283: /* Function to decompress compressed received block bitmap I *see* that it is a function! Start with "Decompress ..." Drop the 'compressed', if you're decompressing it is obvious that it is compressed data. Line 285: * \param color_code_bit[in] Color code 1 for Ones runlength 0 for Zero runlength As asked before, please explain why you call it 'color code' in the first place. Line 297: uint8_t data = 0x0; '= 0' ? Line 304: egprs_compress *compress = egprs_compress::instance(); just ' = instance()' should suffice? Line 307: if (color_code_bit == 1) { 'if (color_code_bit) {' Line 320: color_code_bit ? color_code_bit = 0 : color_code_bit = 1; "color_code_bit = !color_code_bit;" It is a bool now. https://gerrit.osmocom.org/#/c/416/25/src/egprs_rlc_compression.h File src/egprs_rlc_compression.h: Line 7: #define BITS_TO_BYTES(X) (((X) ? (X)/8 : 0) + 1) Then this should be called BITPOS_TO_BYTES instead. This is used only in egprs_rlc_compression.cpp, so move it there. Line 8: #define MOD8(X) ((X) & (0x07)) you're using this define only once, just drop it and use '& 0x7' directly instead. Line 14: } egprs_compress_node; What I meant: here just say "struct egprs_compress_node;", move the definition to egprs_rlc_compression.cpp. Furthermore, since this is C++, you don't need the 'typedef' shim at all. Line 32: { I would move the function definition to .cpp as well Line 41: decode_tree_init(); and move this one to .cpp as well. The idea is to have the public API as lean as possible. https://gerrit.osmocom.org/#/c/416/25/tests/bitcomp/BitcompTest.cpp File tests/bitcomp/BitcompTest.cpp: Line 124: int check_result(bitvec bits, uint8_t *exp_data, int exp_len) cur_bit is unsigned, so should be exp_len (avoid compiler warning with -Wall) Line 150: int itr; make itr unsigned to avoid compiler warning with -Wall Line 164: (test[itr].crbb_len + 7)/8), test[itr].crbb_len You're using 'test[itr]' over and over, rather define a reference (pointer or C++ reference) and use that. -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 25 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Sep 30 16:00:42 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 16:00:42 +0000 Subject: libosmocore[master]: IPAC manufacture-defined measurement pre-processing definitions In-Reply-To: References: Message-ID: Patch Set 1: have you abandoned this patch? -- To view, visit https://gerrit.osmocom.org/812 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1853697f4cff5ff98654fa1cae6c68e28a0076b Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Minh-Quang Nguyen Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Minh-Quang Nguyen Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 16:01:29 2016 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Fri, 30 Sep 2016 16:01:29 +0000 Subject: osmo-pcu[master]: EGPRS: Add EPDAN CRBB Tree based decoding In-Reply-To: References: Message-ID: Patch Set 25: -Code-Review -- To view, visit https://gerrit.osmocom.org/416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce Gerrit-PatchSet: 25 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: pravin Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: arvind.sirsikar Gerrit-Reviewer: pravin Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Sep 30 17:00:07 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 17:00:07 +0000 Subject: [PATCH] osmo-bts[master]: DTX: further AMR SID cache fixes (lc15, sysmo) In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/960 to look at the new patch set (#6). DTX: further AMR SID cache fixes (lc15, sysmo) * consolidate AMR CMR and CMI handling in common/amr.c * use it in save_last_sid() * remove dead code * properly compute RTP payload length for AMR * use save_last_sid() for FR & HR as well * invalidate cached SID if SPEECH frame is received Fixes: OS #1800, #1801 Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed --- M include/osmo-bts/amr.h M include/osmo-bts/msg_utils.h M src/common/amr.c M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 6 files changed, 133 insertions(+), 173 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/60/960/6 diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index 6bdc41f..f313287 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -11,7 +11,8 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, const uint8_t *mr_conf, unsigned int len); -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi); +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 14c2320..f07623d 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -26,8 +26,9 @@ }; void lchan_set_marker(bool t, struct gsm_lchan *lchan); -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update); +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/amr.c b/src/common/amr.c index 56ed430..b5d2c37 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -22,7 +22,8 @@ LOGPC(ss, logl, "\n"); } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) +static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) { unsigned int i; for (i = 0; i < amr_mrc->num_modes; i++) { @@ -32,6 +33,46 @@ return -EINVAL; } +static inline uint8_t set_cmr_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmr) +{ + int rc; + + /* Codec Mode Request is in upper 4 bits of RTP payload header, + * and we simply copy the CMR into the CMC */ + if (cmr == 0xF) { + /* FIXME: we need some state about the last codec mode */ + return 0; + } + + rc = get_amr_mode_idx(amr_mrc, cmr); + if (rc < 0) { + /* FIXME: we need some state about the last codec mode */ + LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); + return 0; + } + return rc; +} + +static inline uint8_t set_cmi_mode_idx(const struct amr_multirate_conf *amr_mrc, + uint8_t cmi) +{ + int rc = get_amr_mode_idx(amr_mrc, cmi); + if (rc < 0) { + LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", + cmi); + return 0; + } + return rc; +} + +void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, + uint8_t cmi, uint8_t cmr) +{ + data[0] = set_cmi_mode_idx(amr_mrc, cmi); + data[1] = set_cmr_mode_idx(amr_mrc, cmr); +} + /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more * comfortable internal data structure */ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index f5a48a3..5c6bbbe 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -99,17 +100,30 @@ } /* store the last SID frame in lchan context */ -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) +/*! \brief Store the last SID frame in lchan context + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] l1_payload buffer with SID data + * \param[in] length length of l1_payload + * \param[in] fn Frame Number for which we check scheduling + * \param[in] update 0 if SID_FIRST, 1 if SID_UPDATE, -1 if not AMR SID + * \param[in] cmr Codec Mode Request (AMR-specific, ignored otherwise) + * \param[in] cmi Codec Mode Indication (AMR-specific, ignored otherwise) + */ +void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, + size_t length, uint32_t fn, int update, uint8_t cmr, + int8_t cmi) { - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); + size_t amr = (update < 0) ? 0 : 2, + copy_len = OSMO_MIN(length + 1, ARRAY_SIZE(lchan->tch.last_sid.buf)); - lchan->tch.last_sid.len = copy_len; + lchan->tch.last_sid.len = copy_len + amr; lchan->tch.last_sid.fn = fn; lchan->tch.last_sid.is_update = update; - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); + if (amr) + amr_set_mode_pref(lchan->tch.last_sid.buf, &lchan->tch.amr_mr, + cmi, cmr); + memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } /*! \brief Check if enough time has passed since last SID (if any) to repeat it diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5ec1ee7..5b5a375 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,85 +199,13 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi, + uint8_t ft) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); memcpy(l1_payload+2, rtp_payload, payload_len); + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -304,6 +232,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -317,32 +246,55 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi, + ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 0e4b2da..655884d 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,19 +282,9 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint32_t fn) + struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi, + uint8_t ft) { - struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - uint8_t *l1_cmi_idx = l1_payload; - uint8_t *l1_cmr_idx = l1_payload+1; - int rc; - - osmo_amr_rtp_dec(rtp_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - #ifdef USE_L1_RTP_MODE memcpy(l1_payload+2, rtp_payload, payload_len); #else @@ -309,72 +299,9 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - /* CMI in downlink tells the L1 encoder which encoding function - * it will use, so we have to use the frame type */ - switch (ft) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - cmi = ft; - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi); - break; - case AMR_NO_DATA: - LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n"); - break; - case AMR_SID: - LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n", - sti ? "UPDATE" : "FIRST", cmi); - break; - default: - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); - return -EINVAL; - break; - } - - rc = get_amr_mode_idx(amr_mrc, cmi); - if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n", - cmi); - *l1_cmi_idx = 0; - } else - *l1_cmi_idx = rc; - - /* Codec Mode Request is in upper 4 bits of RTP payload header, - * and we simply copy the CMR into the CMC */ - if (cmr == 0xF) { - /* FIXME: we need some state about the last codec mode */ - *l1_cmr_idx = 0; - } else { - rc = get_amr_mode_idx(amr_mrc, cmr); - if (rc < 0) { - /* FIXME: we need some state about the last codec mode */ - LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr); - *l1_cmr_idx = 0; - } else - *l1_cmr_idx = rc; - } -#if 0 - /* check for bad quality indication */ - if (bfi == AMR_GOOD) { - /* obtain frame type from AMR FT */ - l1_payload[2] = ft; - } else { - /* bad quality, we should indicate that... */ - if (ft == AMR_SID) { - /* FIXME: Should we do GsmL1_TchPlType_Amr_SidBad? */ - l1_payload[2] = ft; - } else { - l1_payload[2] = ft; - } - } -#endif - - if (ft == AMR_SID) { - save_last_sid(lchan, l1_payload, payload_len, fn, sti); - return -EALREADY; - } - - return payload_len+1; + return payload_len + 2; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -401,6 +328,7 @@ enum osmo_amr_quality bfi; int8_t sti, cmi; int rc; + bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rtp_pl, rtp_pl_len)); @@ -414,34 +342,57 @@ *payload_type = GsmL1_TchPlType_Fr; rc = rtppayload_to_l1_fr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len); } else{ *payload_type = GsmL1_TchPlType_Hr; rc = rtppayload_to_l1_hr(l1_payload, rtp_pl, rtp_pl_len); + if (rc) + is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len); } + if (is_sid) + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, -1, 0, 0); break; #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) case GSM48_CMODE_SPEECH_EFR: *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); + /* FIXME: detect and save EFR SID */ break; #endif case GSM48_CMODE_SPEECH_AMR: + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, + &sti); + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, + cmi); + return false; + } + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", + ft); + return false; + } + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ + marker = true; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } if (marker) { *payload_type = GsmL1_TchPlType_Amr_Onset; rc = 0; - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, - &bfi, &sti); LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, fn); - if (-EALREADY == rc) - return false; + rtp_pl_len, lchan, cmr, cmi, + ft); } break; default: -- To view, visit https://gerrit.osmocom.org/960 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 17:09:45 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 17:09:45 +0000 Subject: [PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#10). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 96 insertions(+), 74 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/10 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 5c6bbbe..99a211f 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include #include - +#include static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; /* only needed for old sysmo firmware */ + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST - cached and send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, + cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + } + + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 5b5a375..bcb1edd 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,13 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi, - uint8_t ft) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -227,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -265,36 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi, - ft); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 655884d..9be8659 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,11 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi, - uint8_t ft) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -299,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -323,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -363,36 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc > 0) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi, - ft); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 10 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 17:13:22 2016 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 30 Sep 2016 17:13:22 +0000 Subject: [PATCH] osmo-bts[master]: DTX: send AMR voice alongside with ONSET In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/961 to look at the new patch set (#14). DTX: send AMR voice alongside with ONSET When ONSET event happens (either via Marker bit or due to unmarked talkspurt) we should first send Onset event to L1 and than send voice data in response to the same PH-RTS.ind. Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 --- M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/l1_if.h M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/l1_if.h M src/osmo-bts-sysmo/tch.c 6 files changed, 32 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/14 diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index cf7ce58..a4378c1 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -441,6 +441,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -464,17 +465,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -502,7 +506,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 88d71bf..adb197d 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -89,7 +89,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index bcb1edd..e246ffb 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -211,7 +211,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -220,7 +222,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -269,7 +271,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -289,14 +291,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3c6db43..09627af 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -436,6 +436,7 @@ uint8_t chan_nr; GsmL1_Prim_t *l1p; struct msgb *nmsg = NULL; + int rc = -1; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; @@ -459,17 +460,20 @@ if (!nmsg) return -ENOMEM; l1p = msgb_l1prim(nmsg); - if (!l1if_tch_encode(lchan, + rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, msg->data, msg->len, u32Fn, - l1sap->u.tch.marker)) { + l1sap->u.tch.marker); + if (rc < 0) { + /* no data encoded for L1: smth will be generated below */ msgb_free(nmsg); nmsg = NULL; } } - /* no message/data, we generate an empty traffic msg */ + /* no message/data, we might generate an empty traffic msg or re-send + cached SID in case of DTX */ if (!nmsg) nmsg = gen_empty_tch_msg(lchan, u32Fn); @@ -497,7 +501,7 @@ /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); - if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */ + if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */ l1sap->u.tch.marker = 0; return ph_tch_req(trx, l1sap->oph.msg, l1sap); } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a90c39b..ece7a01 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -109,7 +109,7 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 9be8659..ca9045e 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -307,7 +307,9 @@ * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl * \param[in] marker RTP header Marker bit (indicates speech onset) - * \returns true if encoding result can be sent further to L1, false otherwise + * \returns 0 if encoding result can be sent further to L1 without extra actions + * positive value if data is ready AND extra actions are required + * negative value otherwise * * This function prepares a msgb with a L1 PH-DATA.req primitive and * queues it into lchan->dl_tch_queue. @@ -316,7 +318,7 @@ * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, +int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; @@ -367,7 +369,7 @@ LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" " Marker: ONSET forced\n", get_value_string(osmo_amr_type_names, ft)); - return true; + return rc; } LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); @@ -387,14 +389,14 @@ if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - return false; + return -EBADMSG; } *len = rc + 1; DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), osmo_hexdump(data, *len)); - return true; + return 0; } static int is_recv_only(uint8_t speech_mode) -- To view, visit https://gerrit.osmocom.org/961 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347 Gerrit-PatchSet: 14 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:36:23 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:36:23 +0000 Subject: [PATCH] libosmocore[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/983 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: If2afbe62e9ceeac8052c7b882ff92a548f3af0bf --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/983/1 diff --git a/configure.ac b/configure.ac index 1b62278..2362ac3 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/983 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If2afbe62e9ceeac8052c7b882ff92a548f3af0bf Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:55:53 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:55:53 +0000 Subject: [PATCH] libosmo-abis[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/984 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I5f69112f58b0a8ce0d848b0b6b543500ee63d133 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/84/984/1 diff --git a/configure.ac b/configure.ac index 92cba96..4f695ab 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/984 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5f69112f58b0a8ce0d848b0b6b543500ee63d133 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:55:53 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:55:53 +0000 Subject: [PATCH] libosmo-abis[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/985 configure: check for pkg-config presence Change-Id: If21ff26a836fd91021e0457ae0316be6b29b4577 --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/85/985/1 diff --git a/configure.ac b/configure.ac index 4f695ab..9a9e88f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,13 @@ AC_PROG_INSTALL LT_INIT([pic-only]) +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + AC_CONFIG_MACRO_DIR([m4]) # The following test is taken from WebKit's webkit.m4 -- To view, visit https://gerrit.osmocom.org/985 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If21ff26a836fd91021e0457ae0316be6b29b4577 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:59:00 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:59:00 +0000 Subject: [PATCH] libosmocore[master]: build: be robust against install-sh files above the root dir In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/983 to look at the new patch set (#2). build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: If2afbe62e9ceeac8052c7b882ff92a548f3af0bf --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/983/2 diff --git a/configure.ac b/configure.ac index 1b62278..e3752b4 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/983 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If2afbe62e9ceeac8052c7b882ff92a548f3af0bf Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:59:28 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:59:28 +0000 Subject: [PATCH] libosmo-abis[master]: build: be robust against install-sh files above the root dir In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/984 to look at the new patch set (#2). build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I5f69112f58b0a8ce0d848b0b6b543500ee63d133 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/84/984/2 diff --git a/configure.ac b/configure.ac index 92cba96..77feaff 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.6 subdir-objects]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/984 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5f69112f58b0a8ce0d848b0b6b543500ee63d133 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:59:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:59:58 +0000 Subject: [PATCH] libosmo-netif[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/986 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: Idcce286e83b802b9cd96cee6230aedd51a660b12 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/86/986/1 diff --git a/configure.ac b/configure.ac index 64a7a1e..135eb57 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc-devel at lists.openbsc.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([subdir-objects dist-bzip2]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/986 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idcce286e83b802b9cd96cee6230aedd51a660b12 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 22:59:58 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 22:59:58 +0000 Subject: [PATCH] libosmo-netif[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/987 configure: check for pkg-config presence Change-Id: Ifaea95befa3d1d8f6f047e22efcd62cb0bd8b287 --- M configure.ac M tests/osmo-pcap-test/configure.ac 2 files changed, 14 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/87/987/1 diff --git a/configure.ac b/configure.ac index 135eb57..3994aff 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,13 @@ LT_INIT AC_PROG_LIBTOOL +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + AC_CONFIG_MACRO_DIR([m4]) dnl checks for header files diff --git a/tests/osmo-pcap-test/configure.ac b/tests/osmo-pcap-test/configure.ac index 0d496db..47fbfe2 100644 --- a/tests/osmo-pcap-test/configure.ac +++ b/tests/osmo-pcap-test/configure.ac @@ -6,6 +6,13 @@ AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax no-dist-gzip dist-bzip2 1.6]) +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -- To view, visit https://gerrit.osmocom.org/987 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifaea95befa3d1d8f6f047e22efcd62cb0bd8b287 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:01:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:01:03 +0000 Subject: [PATCH] libosmo-sccp[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/988 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: Iec88e41c1fe80b436d6d08005871bead540e387d --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/88/988/1 diff --git a/configure.ac b/configure.ac index e19c8da..d2501a6 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/988 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iec88e41c1fe80b436d6d08005871bead540e387d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:01:03 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:01:03 +0000 Subject: [PATCH] libosmo-sccp[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/989 configure: check for pkg-config presence Change-Id: I0066b33ce59d1e107ca8e7389599b232a033ba2e --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/89/989/1 diff --git a/configure.ac b/configure.ac index d2501a6..6446677 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,13 @@ LT_INIT AC_PROG_LIBTOOL +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) -- To view, visit https://gerrit.osmocom.org/989 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0066b33ce59d1e107ca8e7389599b232a033ba2e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:01:30 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:01:30 +0000 Subject: [PATCH] libsmpp34[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/990 configure: check for pkg-config presence Change-Id: I6251b2a8e76e5850a346d88fd3c02435b0b445ad --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libsmpp34 refs/changes/90/990/1 diff --git a/configure.ac b/configure.ac index 6d5b3b3..0d84ffc 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,13 @@ AC_PROG_LIBTOOL AC_PROG_INSTALL +# check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + # Checks for libraries. # Checks for header files. -- To view, visit https://gerrit.osmocom.org/990 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6251b2a8e76e5850a346d88fd3c02435b0b445ad Gerrit-PatchSet: 1 Gerrit-Project: libsmpp34 Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:02:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:02:02 +0000 Subject: [PATCH] openbsc[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/991 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I3b6d9ad4e5af44c2bdf3844c7bf8e8517bd61d8e --- M openbsc/configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/91/991/1 diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 173c6c8..4b00af7 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -3,6 +3,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/991 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3b6d9ad4e5af44c2bdf3844c7bf8e8517bd61d8e Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:02:02 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:02:02 +0000 Subject: [PATCH] openbsc[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/992 configure: check for pkg-config presence Change-Id: I1484fc8b870df6f0aeef0c13078c66d0cfa97e75 --- M openbsc/configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/92/992/1 diff --git a/openbsc/configure.ac b/openbsc/configure.ac index 4b00af7..e2575c1 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -18,6 +18,13 @@ AC_PROG_INSTALL AC_PROG_RANLIB +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + dnl checks for libraries AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""]) AC_SUBST(LIBRARY_DL) -- To view, visit https://gerrit.osmocom.org/992 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1484fc8b870df6f0aeef0c13078c66d0cfa97e75 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:05:13 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:05:13 +0000 Subject: [PATCH] osmo-bts[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/993 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I02153ad52faf1465e9f7821378e04118f17352d2 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/93/993/1 diff --git a/configure.ac b/configure.ac index 0951e18..c6ae2d8 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc-devel at lists.openbsc.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/993 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I02153ad52faf1465e9f7821378e04118f17352d2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:05:13 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:05:13 +0000 Subject: [PATCH] osmo-bts[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/994 configure: check for pkg-config presence Change-Id: Ifee0434dfa275f9faa517c740fd8577930f37188 --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/94/994/1 diff --git a/configure.ac b/configure.ac index c6ae2d8..d35a52a 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,13 @@ AC_PROG_INSTALL AC_PROG_RANLIB +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + dnl checks for header files AC_HEADER_STDC -- To view, visit https://gerrit.osmocom.org/994 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifee0434dfa275f9faa517c740fd8577930f37188 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:05:51 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:05:51 +0000 Subject: [PATCH] osmo-iuh[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/995 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I5aad87b7d4c043f890f4ae2bc5d68cbad6d2c5c7 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/95/995/1 diff --git a/configure.ac b/configure.ac index 249701e..de70e35 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + LT_INIT AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip 1.9 tar-ustar]) -- To view, visit https://gerrit.osmocom.org/995 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5aad87b7d4c043f890f4ae2bc5d68cbad6d2c5c7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:05:52 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:05:52 +0000 Subject: [PATCH] osmo-iuh[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/996 configure: check for pkg-config presence Change-Id: I940558e1b53b0d42291077eba0568f9974df6957 --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/96/996/1 diff --git a/configure.ac b/configure.ac index de70e35..ab7a637 100644 --- a/configure.ac +++ b/configure.ac @@ -22,6 +22,13 @@ AC_PROG_CC AC_PROG_INSTALL +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + PKG_CHECK_MODULES(OSMOCORE, libosmocore) PKG_CHECK_MODULES(OSMOGSM, libosmogsm) PKG_CHECK_MODULES(OSMOVTY, libosmovty) -- To view, visit https://gerrit.osmocom.org/996 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I940558e1b53b0d42291077eba0568f9974df6957 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:06:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:06:49 +0000 Subject: [PATCH] osmo-pcu[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/997 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: Ie9a10f14c5e8c5e9b6ea4910b4b9abb7e70f5e04 --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/97/997/1 diff --git a/configure.ac b/configure.ac index d8fe719..e1a23c0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,9 @@ m4_esyscmd([./git-version-gen .tarball-version]), [osmocom-net-gprs at lists.osmocom.org]) +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) -- To view, visit https://gerrit.osmocom.org/997 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie9a10f14c5e8c5e9b6ea4910b4b9abb7e70f5e04 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:06:49 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:06:49 +0000 Subject: [PATCH] osmo-pcu[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/998 configure: check for pkg-config presence Change-Id: Iaaeb2a926fc3832793dfb3f02e4ced2500950997 --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/98/998/1 diff --git a/configure.ac b/configure.ac index e1a23c0..950be23 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,13 @@ AC_PROG_INSTALL LT_INIT +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + dnl checks for header files AC_HEADER_STDC -- To view, visit https://gerrit.osmocom.org/998 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaaeb2a926fc3832793dfb3f02e4ced2500950997 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:07:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:07:31 +0000 Subject: [PATCH] osmo-sip-connector[master]: build: be robust against install-sh files above the root dir Message-ID: Review at https://gerrit.osmocom.org/999 build: be robust against install-sh files above the root dir Explicitly set AC_CONFIG_AUX_DIR. To reproduce the error avoided by this patch: rm install-sh # in case it was already generated. touch ../install-sh # yes, outside this source tree autoreconf -fi This will produce an error like ... configure.ac:16: error: required file '../ltmain.sh' not found configure.ac:5: installing '../missing' src/Makefile.am: installing '../depcomp' autoreconf: automake failed with exit status: 1 See also automake (vim `which automake`) and look for 'sub locate_aux_dir'. Change-Id: I9c96c087bffb41533ef6fb9b1d00bd903d71693e --- M configure.ac 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/99/999/1 diff --git a/configure.ac b/configure.ac index 0b42951..800a46a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,10 @@ AC_INIT([osmo-sip-connector], m4_esyscmd([./git-version-gen .tarball-version]), [openbsc at lists.osmocom.org]) + +dnl *This* is the root dir, even if an install-sh exists in ../ or ../../ +AC_CONFIG_AUX_DIR([.]) + AM_INIT_AUTOMAKE([dist-bzip2]) dnl kernel style compile messages -- To view, visit https://gerrit.osmocom.org/999 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9c96c087bffb41533ef6fb9b1d00bd903d71693e Gerrit-PatchSet: 1 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Sep 30 23:07:31 2016 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 30 Sep 2016 23:07:31 +0000 Subject: [PATCH] osmo-sip-connector[master]: configure: check for pkg-config presence Message-ID: Review at https://gerrit.osmocom.org/1000 configure: check for pkg-config presence Change-Id: Iaca22089bcb21b56048fa541f588c4ad4bed8f6d --- M configure.ac 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/00/1000/1 diff --git a/configure.ac b/configure.ac index 800a46a..1fa6157 100644 --- a/configure.ac +++ b/configure.ac @@ -7,6 +7,13 @@ AM_INIT_AUTOMAKE([dist-bzip2]) +dnl check for pkg-config (explained in detail in libosmocore/configure.ac) +AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) +if test "x$PKG_CONFIG_INSTALLED" = "xno"; then + AC_MSG_WARN([You need to install pkg-config]) +fi +PKG_PROG_PKG_CONFIG([0.20]) + dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_PROG_CC -- To view, visit https://gerrit.osmocom.org/1000 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaca22089bcb21b56048fa541f588c4ad4bed8f6d Gerrit-PatchSet: 1 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr