From jerlbeck at sysmocom.de Mon Jan 4 17:43:36 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:36 +0100 Subject: [PATCH 5/7] sgsn: Change handling of missing mmctx in gsm48_rx_gmm_ra_upd_req In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-5-git-send-email-jerlbeck@sysmocom.de> Currently the MM context is just overwritten by a call to sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &old_ra_id) even if it has already been found by using the BSSGP info. With the changes made to sgsn_mm_ctx_by_tlli this will never find a MM context if the routing area has changed. If the routing area has not changed, the mmctx has already been found if it exists. This commit splits searching for an MM context (if it hasn't been found already) from checking, whether a found one can really be used. The actual search is removed, so that the MS will be forced to restart the attach procedure, which is less efficient but safe. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gprs_gmm.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 115e898..6e7e5f1 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -1164,9 +1164,21 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, break; } - /* Look-up the MM context based on old RA-ID and TLLI */ - mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &old_ra_id); - if (!mmctx || mmctx->mm_state == GMM_DEREGISTERED) { + if (!mmctx) { + /* BSSGP doesn't give us an mmctx */ + + /* TODO: Check if there is an MM CTX with old_ra_id and + * the P-TMSI (if given, reguired for UMTS) or as last resort + * if the TLLI matches foreign_tlli (P-TMSI). Note that this + * is an optimization to avoid the RA reject (impl detached) + * below, which will cause a new attach cycle. */ + } + + if (!mmctx || !gprs_ra_id_equals(&mmctx->ra, &old_ra_id) || + mmctx->mm_state == GMM_DEREGISTERED) + { + /* We cannot use the mmctx */ + /* send a XID reset to re-set all LLC sequence numbers * in the MS */ LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n"); -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:38 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:38 +0100 Subject: [PATCH 7/7] sgsn: Re-add searching for MM ctx based on TLLI / P-TMSI matches In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-7-git-send-email-jerlbeck@sysmocom.de> If an MM context cannot be found based on BBSGP info and a RA UPDATE REQUEST is received, try to find an MM context with an P-TMSI from which the TLLI could have been derived. This also checks, whether the routing area matches. This is similar to the old behaviour removed by the commits "sgsn: Only look at TLLIs in sgsn_mm_ctx_by_tlli" and "sgsn: Remove tlli_foreign2local", except that this will only be done for RA UPDATE REQUESTs now. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gprs_sgsn.h | 4 ++++ openbsc/src/gprs/gprs_gmm.c | 26 ++++++++++++++++++--- openbsc/src/gprs/gprs_sgsn.c | 25 ++++++++++++++++++++ openbsc/tests/sgsn/sgsn_test.c | 46 ++----------------------------------- openbsc/tests/sgsn/sgsn_test.ok | 1 - 5 files changed, 54 insertions(+), 48 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 61120b1..74f0735 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -178,6 +178,10 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi); struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi); +/* look-up by matching TLLI and P-TMSI (think twice before using this) */ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, + const struct gprs_ra_id *raid); + /* Allocate a new SGSN MM context */ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, const struct gprs_ra_id *raid); diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 6e7e5f1..212c7d7 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -1172,13 +1172,33 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, * if the TLLI matches foreign_tlli (P-TMSI). Note that this * is an optimization to avoid the RA reject (impl detached) * below, which will cause a new attach cycle. */ - } - - if (!mmctx || !gprs_ra_id_equals(&mmctx->ra, &old_ra_id) || + /* 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); + if (mmctx) { + LOGMMCTXP(LOGL_INFO, mmctx, + "Looked up by matching TLLI and P_TMSI. " + "BSSGP TLLI: %08x, P-TMSI: %08x (%08x), " + "TLLI: %08x (%08x), RA: %d-%d-%d-%d\n", + msgb_tlli(msg), + mmctx->p_tmsi, mmctx->p_tmsi_old, + mmctx->tlli, mmctx->tlli_new, + mmctx->ra.mcc, mmctx->ra.mnc, + mmctx->ra.lac, mmctx->ra.rac); + + mmctx->mm_state = GMM_COMMON_PROC_INIT; + } + } else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) || mmctx->mm_state == GMM_DEREGISTERED) { /* We cannot use the mmctx */ + LOGMMCTXP(LOGL_INFO, mmctx, + "The MM context cannot be used, RA: %d-%d-%d-%d\n", + mmctx->ra.mcc, mmctx->ra.mnc, + mmctx->ra.lac, mmctx->ra.rac); + mmctx = NULL; + } + if (!mmctx) { /* send a XID reset to re-set all LLC sequence numbers * in the MS */ LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n"); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index f71066d..b7bda49 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -105,6 +105,31 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, return NULL; } +struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, + const struct gprs_ra_id *raid) +{ + struct sgsn_mm_ctx *ctx; + int tlli_type; + + /* TODO: Also check the P_TMSI signature to be safe. That signature + * should be different (at least with a sufficiently high probability) + * after SGSN restarts and for multiple SGSN instances. + */ + + tlli_type = gprs_tlli_type(tlli); + if (tlli_type != TLLI_FOREIGN && tlli_type != TLLI_LOCAL) + return NULL; + + llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { + if ((gprs_tmsi2tlli(ctx->p_tmsi, tlli_type) == tlli || + gprs_tmsi2tlli(ctx->p_tmsi_old, tlli_type) == tlli) && + gprs_ra_id_equals(raid, &ctx->ra)) + return ctx; + } + + return NULL; +} + struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t p_tmsi) { struct sgsn_mm_ctx *ctx; diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index d27b755..1acd6f2 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1995,7 +1995,6 @@ static void test_gmm_routing_areas(void) OSMO_ASSERT(ctx->p_tmsi == ptmsi1); OSMO_ASSERT(ctx->tlli == ms_tlli); - printf(" - RA Update Request (RA 1 -> RA 2)\n"); /* inject the RA update request */ @@ -2005,50 +2004,9 @@ static void test_gmm_routing_areas(void) send_0408_message(ctx->llme, ms_tlli, &raid2, ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); - /* we expect an RA update reject (and a LLC XID RESET) */ - OSMO_ASSERT(sgsn_tx_counter == 2); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); - /* this has killed the LLE/LLME */ - - printf(" - Attach Request (RA 2)\n"); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 1); - lle = gprs_lle_get_or_create(ms_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, ms_tlli, &raid2, - attach_req2, ARRAY_SIZE(attach_req2)); - - ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - - /* we expect an attach accept */ + /* we expect an RA update accept */ OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); - - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); - ptmsi1 = received_ptmsi; - - /* inject the attach complete */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); - OSMO_ASSERT(ictx != NULL); - OSMO_ASSERT(ictx == ctx); - - send_0408_message(ctx->llme, ms_tlli, &raid2, - attach_compl, ARRAY_SIZE(attach_compl)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); printf(" - RA Update Request (RA other -> RA 2)\n"); diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index 5b8fc40..cdd2006 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -29,7 +29,6 @@ Testing routing area changes - Attach Request (RA 1) - RA Update Request (RA 1 -> RA 1) - RA Update Request (RA 1 -> RA 2) - - Attach Request (RA 2) - RA Update Request (RA other -> RA 2) - Attach Request (RA 2) - RA Update Request (RA 2 -> RA 2) -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:33 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:33 +0100 Subject: [PATCH 2/7] sgsn/test: Add bssgp_raid parameter to send_0408_message In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-2-git-send-email-jerlbeck@sysmocom.de> The BSSGP cell identifier is used to get the RA for the TLLI lookup. The send_0408_message function used in the tests does not set this, so the RA identifier is always 0-0-0-0. This commit adds a parameters to pass the RAID and adds missing dummy RAIDs. Note that the CI can still not be set and thus is always 0. Sponsored-by: On-Waves ehf --- openbsc/tests/sgsn/sgsn_test.c | 55 +++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 01e94c7..6d7ba38 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -186,6 +186,7 @@ static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid) } static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli, + const struct gprs_ra_id *bssgp_raid, const uint8_t *data, size_t data_len) { struct msgb *msg; @@ -195,6 +196,7 @@ static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli, msg = create_msg(data, data_len); msgb_tlli(msg) = tlli; + bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0); gsm0408_gprs_rcvmsg(msg, llme); msgb_free(msg); } @@ -728,7 +730,7 @@ static void test_gmm_detach(void) ctx = alloc_mm_ctx(local_tlli, &raid); /* inject the detach */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, detach_req, ARRAY_SIZE(detach_req)); /* verify that a single message (hopefully the Detach Accept) has been @@ -769,7 +771,7 @@ static void test_gmm_detach_power_off(void) ctx = alloc_mm_ctx(local_tlli, &raid); /* inject the detach */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, detach_req, ARRAY_SIZE(detach_req)); /* verify that no message (and therefore no Detach Accept) has been @@ -789,6 +791,7 @@ static void test_gmm_detach_power_off(void) */ static void test_gmm_detach_no_mmctx(void) { + struct gprs_ra_id raid = { 0, }; struct gprs_llc_lle *lle; uint32_t local_tlli; @@ -809,7 +812,7 @@ static void test_gmm_detach_no_mmctx(void) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* inject the detach */ - send_0408_message(lle->llme, local_tlli, + send_0408_message(lle->llme, local_tlli, &raid, detach_req, ARRAY_SIZE(detach_req)); /* verify that the LLME is gone */ @@ -824,6 +827,7 @@ static void test_gmm_detach_no_mmctx(void) */ static void test_gmm_detach_accept_unexpected(void) { + struct gprs_ra_id raid = { 0, }; struct gprs_llc_lle *lle; uint32_t local_tlli; @@ -841,7 +845,7 @@ static void test_gmm_detach_accept_unexpected(void) lle = gprs_lle_get_or_create(local_tlli, 3); /* inject the detach */ - send_0408_message(lle->llme, local_tlli, + send_0408_message(lle->llme, local_tlli, &raid, detach_acc, ARRAY_SIZE(detach_acc)); /* verify that no message (and therefore no Status or XID reset) has been @@ -859,6 +863,7 @@ static void test_gmm_detach_accept_unexpected(void) */ static void test_gmm_status_no_mmctx(void) { + struct gprs_ra_id raid = { 0, }; struct gprs_llc_lle *lle; uint32_t local_tlli; @@ -877,7 +882,7 @@ static void test_gmm_status_no_mmctx(void) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* inject the detach */ - send_0408_message(lle->llme, local_tlli, + send_0408_message(lle->llme, local_tlli, &raid, gmm_status, ARRAY_SIZE(gmm_status)); /* verify that no message has been sent by the SGSN */ @@ -952,7 +957,7 @@ static void test_gmm_attach(int retry) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, attach_req, ARRAY_SIZE(attach_req)); ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); @@ -963,14 +968,14 @@ static void test_gmm_attach(int retry) OSMO_ASSERT(sgsn_tx_counter == 1); /* inject the identity response (IMEI) */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); /* we expect an identity request (IMSI) */ OSMO_ASSERT(sgsn_tx_counter == 1); /* inject the identity response (IMSI) */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi)); /* check that the MM context has not been removed due to a failed @@ -984,7 +989,7 @@ retry_attach_req: if (retry && sgsn_tx_counter == 0) { fprintf(stderr, "Retrying attach request\n"); /* re-inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, attach_req, ARRAY_SIZE(attach_req)); } @@ -992,7 +997,7 @@ retry_attach_req: /* we got an auth & ciph request */ /* inject the auth & ciph response */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp)); /* check that the MM context has not been removed due to a @@ -1014,7 +1019,7 @@ retry_attach_req: local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); /* inject the attach complete */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, attach_compl, ARRAY_SIZE(attach_compl)); OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); @@ -1023,7 +1028,7 @@ retry_attach_req: OSMO_ASSERT(sgsn_tx_counter == 0); /* inject the detach */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, detach_req, ARRAY_SIZE(detach_req)); /* verify that things are gone */ @@ -1470,7 +1475,7 @@ static void test_gmm_reject(void) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* Inject the Request message */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, test->msg, test->msg_len); /* We expect a Reject message */ @@ -1540,7 +1545,7 @@ static void test_gmm_cancel(void) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, attach_req, ARRAY_SIZE(attach_req)); ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); @@ -1551,14 +1556,14 @@ static void test_gmm_cancel(void) OSMO_ASSERT(sgsn_tx_counter == 1); /* inject the identity response (IMEI) */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); /* we expect an identity request (IMSI) */ OSMO_ASSERT(sgsn_tx_counter == 1); /* inject the identity response (IMSI) */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi)); /* check that the MM context has not been removed due to a failed @@ -1576,7 +1581,7 @@ static void test_gmm_cancel(void) local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); /* inject the attach complete */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, attach_compl, ARRAY_SIZE(attach_compl)); OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); @@ -1688,7 +1693,7 @@ static void test_gmm_ptmsi_allocation(void) OSMO_ASSERT(count(gprs_llme_list()) == 1); /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, attach_req, ARRAY_SIZE(attach_req)); ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); @@ -1703,7 +1708,7 @@ static void test_gmm_ptmsi_allocation(void) OSMO_ASSERT(sgsn_tx_counter == 1); /* inject the identity response (IMEI) */ - send_0408_message(ctx->llme, foreign_tlli, + send_0408_message(ctx->llme, foreign_tlli, &raid, ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); /* check that the MM context has not been removed due to a failed @@ -1719,7 +1724,7 @@ static void test_gmm_ptmsi_allocation(void) OSMO_ASSERT(received_ptmsi == ptmsi1); /* we ignore this and send the attach again */ - send_0408_message(lle->llme, foreign_tlli, + send_0408_message(lle->llme, foreign_tlli, &raid, attach_req, ARRAY_SIZE(attach_req)); /* the allocated P-TMSI should be the same */ @@ -1736,7 +1741,7 @@ static void test_gmm_ptmsi_allocation(void) /* inject the attach complete */ local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, attach_compl, ARRAY_SIZE(attach_compl)); /* we don't expect a response */ @@ -1749,7 +1754,7 @@ static void test_gmm_ptmsi_allocation(void) printf(" - Repeated RA Update Request\n"); /* inject the RA update request */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, ra_upd_req, ARRAY_SIZE(ra_upd_req)); /* we expect an RA update accept */ @@ -1762,7 +1767,7 @@ static void test_gmm_ptmsi_allocation(void) ptmsi2 = ctx->p_tmsi; /* repeat the RA update request */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, ra_upd_req, ARRAY_SIZE(ra_upd_req)); /* we expect an RA update accept */ @@ -1776,7 +1781,7 @@ static void test_gmm_ptmsi_allocation(void) /* inject the RA update complete */ local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL); - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); /* we don't expect a response */ @@ -1787,7 +1792,7 @@ static void test_gmm_ptmsi_allocation(void) OSMO_ASSERT(ctx->p_tmsi == ptmsi2); /* inject the detach */ - send_0408_message(ctx->llme, local_tlli, + send_0408_message(ctx->llme, local_tlli, &raid, detach_req, ARRAY_SIZE(detach_req)); /* verify that things are gone */ -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:34 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:34 +0100 Subject: [PATCH 3/7] sgsn: Make ra_id_equals available as gprs_ra_id_equals In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-3-git-send-email-jerlbeck@sysmocom.de> The function is moved to gprs_utils.c, renamed, and made non-static to be usable in other modules, too. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gprs_utils.h | 2 ++ openbsc/src/gprs/gprs_sgsn.c | 11 ++--------- openbsc/src/gprs/gprs_utils.c | 7 +++++++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/gprs_utils.h b/openbsc/include/openbsc/gprs_utils.h index 6880e05..474eb45 100644 --- a/openbsc/include/openbsc/gprs_utils.h +++ b/openbsc/include/openbsc/gprs_utils.h @@ -25,6 +25,7 @@ #include struct msgb; +struct gprs_ra_id; struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, @@ -52,3 +53,4 @@ int gprs_match_tlv(uint8_t **data, size_t *data_len, int gprs_shift_lv(uint8_t **data, size_t *data_len, uint8_t **value, size_t *value_len); +int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index c4dc9d7..8f8bdc6 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -90,13 +90,6 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = { .class_id = OSMO_STATS_CLASS_SUBSCRIBER, }; -static int ra_id_equals(const struct gprs_ra_id *id1, - const struct gprs_ra_id *id2) -{ - return (id1->mcc == id2->mcc && id1->mnc == id2->mnc && - id1->lac == id2->lac && id1->rac == id2->rac); -} - /* See 03.02 Chapter 2.6 */ static inline uint32_t tlli_foreign(uint32_t tlli) { @@ -112,7 +105,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { if (tlli == ctx->tlli && - ra_id_equals(raid, &ctx->ra)) + gprs_ra_id_equals(raid, &ctx->ra)) return ctx; } @@ -130,7 +123,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, case TLLI_FOREIGN: llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { if (tlli == tlli_foreign(ctx->tlli) && - ra_id_equals(raid, &ctx->ra)) + gprs_ra_id_equals(raid, &ctx->ra)) return ctx; } break; diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c index ad479db..895a033 100644 --- a/openbsc/src/gprs/gprs_utils.c +++ b/openbsc/src/gprs/gprs_utils.c @@ -26,6 +26,7 @@ #include #include +#include #include @@ -399,3 +400,9 @@ fail: return -1; } +int gprs_ra_id_equals(const struct gprs_ra_id *id1, + const struct gprs_ra_id *id2) +{ + return (id1->mcc == id2->mcc && id1->mnc == id2->mnc && + id1->lac == id2->lac && id1->rac == id2->rac); +} -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:35 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:35 +0100 Subject: [PATCH 4/7] sgsn: Only look at TLLIs in sgsn_mm_ctx_by_tlli In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-4-git-send-email-jerlbeck@sysmocom.de> Currently the code also matches the TLLI against LOCAL and FOREIGN mappings of the P-TMSI, thus eventually finding MM contexts not consistent with the TLLI (both tlli and tlli_new differ). On the other hand, tlli_new is not checked at all. This commit changes the function to only look at mmctx->tlli, mmctx->tlli_new, and the routing area. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gprs_sgsn.c | 31 +------------------------------ openbsc/tests/sgsn/sgsn_test.c | 2 +- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 8f8bdc6..f71066d 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -90,47 +90,18 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = { .class_id = OSMO_STATS_CLASS_SUBSCRIBER, }; -/* See 03.02 Chapter 2.6 */ -static inline uint32_t tlli_foreign(uint32_t tlli) -{ - return ((tlli | 0x80000000) & ~0x40000000); -} - /* 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) { struct sgsn_mm_ctx *ctx; - int tlli_type; llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if (tlli == ctx->tlli && + if ((tlli == ctx->tlli || tlli == ctx->tlli_new) && gprs_ra_id_equals(raid, &ctx->ra)) return ctx; } - tlli_type = gprs_tlli_type(tlli); - switch (tlli_type) { - case TLLI_LOCAL: - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if ((ctx->p_tmsi | 0xC0000000) == tlli || - (ctx->p_tmsi_old && (ctx->p_tmsi_old | 0xC0000000) == tlli)) { - ctx->tlli = tlli; - return ctx; - } - } - break; - case TLLI_FOREIGN: - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if (tlli == tlli_foreign(ctx->tlli) && - gprs_ra_id_equals(raid, &ctx->ra)) - return ctx; - } - break; - default: - break; - } - return NULL; } diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 6d7ba38..2098972 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1607,7 +1607,7 @@ static void test_gmm_cancel(void) */ static void test_gmm_ptmsi_allocation(void) { - struct gprs_ra_id raid = { 0, }; + struct gprs_ra_id raid = {332, 112, 16464, 96}; struct sgsn_mm_ctx *ctx = NULL; struct sgsn_mm_ctx *ictx; uint32_t foreign_tlli; -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:32 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:32 +0100 Subject: [PATCH 1/7] sgsn: Remove tlli_foreign2local Message-ID: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Currently foreign TLLI are sometimes mapped to local TLLI in the hope that they will match. This seems to sometimes introduce inconsisties, possibly leading to a failing assertion in _bssgp_tx_dl_ud. This mapping should probably reduce the allocation of additional LLME during routing area changes. This commit removes tlli_foreign2local. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gprs_llc.c | 24 ++---------------------- openbsc/tests/sgsn/sgsn_test.c | 5 ----- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 936354a..06ccd4c 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -39,20 +39,6 @@ static struct gprs_llc_llme *llme_alloc(uint32_t tlli); /* If the TLLI is foreign, return its local version */ -static inline uint32_t tlli_foreign2local(uint32_t tlli) -{ - uint32_t new_tlli; - - if (gprs_tlli_type(tlli) == TLLI_FOREIGN) { - new_tlli = tlli | 0x40000000; - LOGP(DLLC, LOGL_NOTICE, "TLLI 0x%08x is foreign, converting to " - "local TLLI 0x%08x\n", tlli, new_tlli); - } else - new_tlli = tlli; - - return new_tlli; -} - /* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU * to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx) @@ -72,9 +58,7 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx) /* make sure we only send it to the right llme */ OSMO_ASSERT(msgb_tlli(msg) == mmctx->llme->tlli - || msgb_tlli(msg) == mmctx->llme->old_tlli - || tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->tlli - || tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->old_tlli); + || msgb_tlli(msg) == mmctx->llme->old_tlli); } memcpy(&dup.qos_profile, qos_profile_default, sizeof(qos_profile_default)); @@ -175,10 +159,6 @@ struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi) if (lle) return lle; - lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi); - if (lle) - return lle; - LOGP(DLLC, LOGL_NOTICE, "LLC: unknown TLLI 0x%08x, " "creating LLME on the fly\n", tlli); llme = llme_alloc(tlli); @@ -204,7 +184,7 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli, /* Maybe it is a routing area update but we already know this sapi? */ if (gprs_tlli_type(tlli) == TLLI_FOREIGN) { - lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi); + lle = lle_by_tlli_sapi(tlli, sapi); if (lle) { LOGP(DLLC, LOGL_NOTICE, "LLC RX: Found a local entry for TLLI 0x%08x\n", diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 859223f..01e94c7 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -203,11 +203,9 @@ static void test_llme(void) { struct gprs_llc_lle *lle, *lle_copy; uint32_t local_tlli; - uint32_t foreign_tlli; printf("Testing LLME allocations\n"); local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL); - foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN); /* initial state */ OSMO_ASSERT(count(gprs_llme_list()) == 0); @@ -221,9 +219,6 @@ static void test_llme(void) lle_copy = gprs_lle_get_or_create(local_tlli, 3); OSMO_ASSERT(lle == lle_copy); OSMO_ASSERT(count(gprs_llme_list()) == 1); - lle_copy = gprs_lle_get_or_create(foreign_tlli, 3); - OSMO_ASSERT(lle == lle_copy); - OSMO_ASSERT(count(gprs_llme_list()) == 1); /* unassign which should delete it*/ gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL); -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 17:43:37 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 18:43:37 +0100 Subject: [PATCH 6/7] sgsn/test: Add test case test_gmm_routing_areas In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451929418-32581-6-git-send-email-jerlbeck@sysmocom.de> This test add different cases of routing area changes. Sponsored-by: On-Waves ehf --- openbsc/tests/sgsn/sgsn_test.c | 347 ++++++++++++++++++++++++++++++++++++++++ openbsc/tests/sgsn/sgsn_test.ok | 8 + 2 files changed, 355 insertions(+) diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 2098972..d27b755 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1805,6 +1805,352 @@ static void test_gmm_ptmsi_allocation(void) cleanup_test(); } +/* + * Test changing of routing areas + */ +static void test_gmm_routing_areas(void) +{ + struct gprs_ra_id raid1 = {332, 112, 16464, 96}; + struct gprs_ra_id raid2 = {332, 112, 16464, 97}; + struct sgsn_mm_ctx *ctx = NULL; + struct sgsn_mm_ctx *ictx; + uint32_t ptmsi1; + uint32_t received_ptmsi; + uint32_t ms_tlli = 0; + struct gprs_llc_lle *lle; + const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; + + /* DTAP - Attach Request (IMSI 12131415161718) */ + static const unsigned char attach_req[] = { + 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, + 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, + 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, + 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, + 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, + 0x00, + }; + + /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */ + static const unsigned char attach_req2[] = { + 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, + 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19, + 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, + 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, + 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, + 0x00, + }; + + /* DTAP - Identity Response IMEI */ + static const unsigned char ident_resp_imei[] = { + 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, + 0x56 + }; + + /* DTAP - Attach Complete */ + static const unsigned char attach_compl[] = { + 0x08, 0x03 + }; + + /* DTAP - Routing Area Update Request (coming from RA 1) */ + static const unsigned char ra_upd_req1[] = { + 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, + 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Request (coming from RA 2) */ + static const unsigned char ra_upd_req2[] = { + 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, + 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Request (coming from RA other) */ + /* raid_other = {443, 223, 16464, 98}; */ + static const unsigned char ra_upd_req_other[] = { + 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50, + 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Complete */ + static const unsigned char ra_upd_complete[] = { + 0x08, 0x0a + }; + + /* DTAP - Detach Request (MO) */ + /* normal detach, power_off = 1 */ + static const unsigned char detach_req[] = { + 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, + 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb + }; + + sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN; + + printf("Testing routing area changes\n"); + + /* reset the PRNG used by sgsn_alloc_ptmsi */ + srand(1); + + ptmsi1 = GSM_RESERVED_TMSI; + + printf(" - Attach Request (RA 1)\n"); + + ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid1, + attach_req, ARRAY_SIZE(attach_req)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an identity request (IMEI) */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ); + OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + /* inject the identity response (IMEI) */ + send_0408_message(ctx->llme, ms_tlli, &raid1, + ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); + + /* check that the MM context has not been removed due to a failed + * authorization */ + OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1)); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid1, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA 1 -> RA 1)\n"); + + /* inject the RA update request */ + send_0408_message(ctx->llme, ms_tlli, &raid1, + ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); + + /* we expect an RA update accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); + // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + OSMO_ASSERT(ctx->p_tmsi != ptmsi1); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the RA update complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid1, + ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + OSMO_ASSERT(ctx->tlli == ms_tlli); + + + printf(" - RA Update Request (RA 1 -> RA 2)\n"); + + /* inject the RA update request */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN); + + /* It is coming from RA 1 => ra_upd_req1 */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); + + /* we expect an RA update reject (and a LLC XID RESET) */ + OSMO_ASSERT(sgsn_tx_counter == 2); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); + /* this has killed the LLE/LLME */ + + printf(" - Attach Request (RA 2)\n"); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 1); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid2, + attach_req2, ARRAY_SIZE(attach_req2)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ictx != NULL); + OSMO_ASSERT(ictx == ctx); + + send_0408_message(ctx->llme, ms_tlli, &raid2, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA other -> RA 2)\n"); + + /* inject the RA update request */ + ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN); + + /* It is coming from RA 1 => ra_upd_req1 */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other)); + + /* we expect an RA update reject (and a LLC XID RESET) */ + OSMO_ASSERT(sgsn_tx_counter == 2); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); + /* this has killed the LLE/LLME */ + + printf(" - Attach Request (RA 2)\n"); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 1); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid2, + attach_req2, ARRAY_SIZE(attach_req2)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ictx != NULL); + OSMO_ASSERT(ictx == ctx); + + send_0408_message(ctx->llme, ms_tlli, &raid2, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA 2 -> RA 2)\n"); + + /* inject the RA update request */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req2, ARRAY_SIZE(ra_upd_req2)); + + /* we expect an RA update accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + OSMO_ASSERT(ctx->p_tmsi != ptmsi1); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the RA update complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + OSMO_ASSERT(ctx->tlli == ms_tlli); + + + /* inject the detach */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + detach_req, ARRAY_SIZE(detach_req)); + + /* verify that things are gone */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(!ictx); + + sgsn->cfg.auth_policy = saved_auth_policy; + + cleanup_test(); +} + static void test_apn_matching(void) { struct apn_ctx *actx, *actxs[9]; @@ -2129,6 +2475,7 @@ int main(int argc, char **argv) test_gmm_reject(); test_gmm_cancel(); test_gmm_ptmsi_allocation(); + test_gmm_routing_areas(); test_apn_matching(); test_ggsn_selection(); printf("Done\n"); diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index 7913a39..5b8fc40 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -25,6 +25,14 @@ Testing P-TMSI allocation - sgsn_alloc_ptmsi - Repeated Attach Request - Repeated RA Update Request +Testing routing area changes + - Attach Request (RA 1) + - RA Update Request (RA 1 -> RA 1) + - RA Update Request (RA 1 -> RA 2) + - Attach Request (RA 2) + - RA Update Request (RA other -> RA 2) + - Attach Request (RA 2) + - RA Update Request (RA 2 -> RA 2) Testing APN matching Testing GGSN selection Done -- 1.9.1 From jerlbeck at sysmocom.de Mon Jan 4 18:11:07 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Jan 2016 19:11:07 +0100 Subject: [PATCH] ns: Handle procedure changes for UDP in TS 48.016 Message-ID: <1451931067-7511-1-git-send-email-jerlbeck@sysmocom.de> In TS 48.016 the network service procedure change depending on the network link type being used. This mainly affects the reset and test procedures. Not obeying these changes makes it impossible to set up NSVC with equipment relying on them. This commits adds the possibility to be compliant to either specification by adding a configuration option to select the compliance mode explicitly for each NSE. The TS 48.016 mode mainly gains conformance, but hinders dynamic NSCV establishment since there aren't any RESET messages. Therefore that mode is not enabled by default. Note that dynamic NSVC establishment as defined by TS 48.016 is not being implemented, since it does not work with routers using network address translation (NAT). New VTY commands (config-ns node): - nse <0-65535> compliance ts08.16 Just use UDP instead of FR - nse <0-65535> compliance ts48.016 Use the modified procedures Sponsored-by: On-Waves ehf --- include/osmocom/gprs/gprs_ns.h | 8 ++++++ src/gb/gprs_ns.c | 62 ++++++++++++++++++++++++++++++++++++------ src/gb/gprs_ns_vty.c | 31 +++++++++++++++++++++ 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h index 7c3b23c..1219307 100644 --- a/include/osmocom/gprs/gprs_ns.h +++ b/include/osmocom/gprs/gprs_ns.h @@ -61,6 +61,11 @@ enum gprs_ns_cs { GPRS_NS_CS_ERROR, /*!< Failed to process message */ }; +enum gprs_ns_spec { + GPRS_NS_TS_08_16 = 0, + GPRS_NS_TS_48_016, +}; + struct gprs_nsvc; /*! \brief Osmocom GPRS callback function type */ typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, @@ -120,10 +125,13 @@ struct gprs_nsvc { enum nsvc_timer_mode timer_mode; struct timeval timer_started; int alive_retries; + enum gprs_ns_spec compliance; unsigned int remote_end_is_sgsn:1; unsigned int persistent:1; unsigned int nsvci_is_valid:1; + unsigned int static_config:1; + unsigned int config_completed:1; struct rate_ctr_group *ctrg; struct osmo_stat_item_group *statg; diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index a29c946..0e874cf 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -149,11 +149,28 @@ static const struct osmo_stat_item_group_desc nsvc_statg_desc = { .class_id = OSMO_STATS_CLASS_PEER, }; +static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode); + #define CHECK_TX_RC(rc, nsvc) \ if (rc < 0) \ LOGP(DNS, LOGL_ERROR, "TX failed (%d) to peer %s\n", \ rc, gprs_ns_ll_str(nsvc)); +static int enable_reset_block_proc(const struct gprs_nsvc *nsvc) +{ + return nsvc->compliance != GPRS_NS_TS_48_016 || + !nsvc->static_config || + nsvc->ll != GPRS_NS_LL_UDP; +} + +static int continue_test_proc(const struct gprs_nsvc *nsvc) +{ + return nsvc->compliance == GPRS_NS_TS_48_016 && + nsvc->static_config && + nsvc->ll == GPRS_NS_LL_UDP && + nsvc->remote_end_is_sgsn; +} + struct msgb *gprs_ns_msgb_alloc(void) { struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, @@ -588,16 +605,24 @@ static void gprs_ns_timer_cb(void *data) nsvc->alive_retries++; if (nsvc->alive_retries > nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]) { - /* mark as dead and blocked */ - nsvc->state = NSE_S_BLOCKED; - rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]); - rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]); LOGP(DNS, LOGL_NOTICE, "NSEI=%u Tns-alive expired more then " "%u times, blocking NS-VC\n", nsvc->nsei, nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]); + /* mark as dead */ + nsvc->state = nsvc->state & ~NSE_S_ALIVE; + rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]); ns_osmo_signal_dispatch(nsvc, S_NS_ALIVE_EXP, 0); - ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, NS_CAUSE_NSVC_BLOCKED); + + if (continue_test_proc(nsvc)) { + nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST); + } else if (enable_reset_block_proc(nsvc)) { + /* mark as blocked */ + nsvc->state = NSE_S_BLOCKED; + rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]); + ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, + NS_CAUSE_NSVC_BLOCKED); + } return; } /* Tns-test case: send NS-ALIVE PDU */ @@ -1109,6 +1134,14 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg, return rc; rc = 0; + } else if (nsvc->static_config && !nsvc->config_completed) { + + if (!enable_reset_block_proc(nsvc)) { + nsvc->state = NSE_S_ALIVE; + nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST); + } + + nsvc->config_completed = 1; } if (nsvc) @@ -1311,10 +1344,18 @@ int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg, * NS-ALIVE out of the blue, we might have been re-started * and should send a NS-RESET to make sure everything recovers * fine. */ - if ((*nsvc)->state == NSE_S_BLOCKED) + if ((*nsvc)->state == NSE_S_BLOCKED) { rc = gprs_nsvc_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE); - else if (!((*nsvc)->state & NSE_S_RESET)) + } else if (!((*nsvc)->state & NSE_S_RESET)) { rc = gprs_ns_tx_alive_ack(*nsvc); + if (!enable_reset_block_proc(*nsvc) && + !((*nsvc)->state & NSE_S_ALIVE)) + { + /* start the test procedure */ + gprs_ns_tx_simple((*nsvc), NS_PDUT_ALIVE); + nsvc_start_timer((*nsvc), NSVC_TIMER_TNS_TEST); + } + } break; case NS_PDUT_ALIVE_ACK: if ((*nsvc)->timer_mode == NSVC_TIMER_TNS_ALIVE) @@ -1605,7 +1646,12 @@ struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi, nsvc->nsei = nsei; nsvc->remote_end_is_sgsn = 1; - gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION); + if (enable_reset_block_proc(nsvc)) { + gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION); + } else if (continue_test_proc(nsvc)) { + nsvc->state = NSE_S_ALIVE; + nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST); + } return nsvc; } diff --git a/src/gb/gprs_ns_vty.c b/src/gb/gprs_ns_vty.c index 5a951dc..1353bf3 100644 --- a/src/gb/gprs_ns_vty.c +++ b/src/gb/gprs_ns_vty.c @@ -91,6 +91,11 @@ static int config_write_ns(struct vty *vty) vty_out(vty, " nse %u remote-role %s%s", nsvc->nsei, nsvc->remote_end_is_sgsn ? "sgsn" : "bss", VTY_NEWLINE); + vty_out(vty, " nse %u compliance %s%s", + nsvc->nsei, + nsvc->compliance == GPRS_NS_TS_08_16 ? + "ts08.16" : "ts48.016", + VTY_NEWLINE); switch (nsvc->ll) { case GPRS_NS_LL_UDP: vty_out(vty, " nse %u encapsulation udp%s", nsvc->nsei, @@ -257,6 +262,7 @@ DEFUN(cfg_nse_nsvc, cfg_nse_nsvci_cmd, if (!nsvc) { nsvc = gprs_nsvc_create(vty_nsi, nsvci); nsvc->nsei = nsei; + nsvc->static_config = 1; } nsvc->nsvci = nsvci; /* All NSVCs that are explicitly configured by VTY are @@ -389,6 +395,30 @@ DEFUN(cfg_nse_remoterole, cfg_nse_remoterole_cmd, return CMD_SUCCESS; } +DEFUN(cfg_nse_compliance, cfg_nse_compliance_cmd, + "nse <0-65535> compliance (ts08.16|ts48.016)", + NSE_CMD_STR + "Set protocol compliance\n" + "Use 3GPP TS 08.16\n" + "Use 3GPP TS 48.016\n") +{ + uint16_t nsei = atoi(argv[0]); + struct gprs_nsvc *nsvc; + + nsvc = gprs_nsvc_by_nsei(vty_nsi, nsei); + if (!nsvc) { + vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE); + return CMD_WARNING; + } + + if (!strcmp(argv[1], "ts08.16")) + nsvc->compliance = GPRS_NS_TS_08_16; + else + nsvc->compliance = GPRS_NS_TS_48_016; + + return CMD_SUCCESS; +} + DEFUN(cfg_no_nse, cfg_no_nse_cmd, "no nse <0-65535>", "Delete Persistent NS Entity\n" @@ -593,6 +623,7 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi) install_element(L_NS_NODE, &cfg_nse_fr_dlci_cmd); install_element(L_NS_NODE, &cfg_nse_encaps_cmd); install_element(L_NS_NODE, &cfg_nse_remoterole_cmd); + install_element(L_NS_NODE, &cfg_nse_compliance_cmd); install_element(L_NS_NODE, &cfg_no_nse_cmd); install_element(L_NS_NODE, &cfg_ns_timer_cmd); install_element(L_NS_NODE, &cfg_nsip_local_ip_cmd); -- 1.9.1 From jerlbeck at sysmocom.de Tue Jan 5 09:29:19 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 10:29:19 +0100 Subject: [PATCH] ns/vty: Only write compliance command if value changed In-Reply-To: <1451931067-7511-1-git-send-email-jerlbeck@sysmocom.de> References: <1451931067-7511-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451986159-10049-1-git-send-email-jerlbeck@sysmocom.de> Currently the 'compliance' command is always written on 'write'. This commit changes this to only write it, if the compliance value has been set to 'ts48.016'. Thus it is not written if the default value is used. Sponsored-by: On-Waves ehf --- src/gb/gprs_ns_vty.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gb/gprs_ns_vty.c b/src/gb/gprs_ns_vty.c index 1353bf3..0382e10 100644 --- a/src/gb/gprs_ns_vty.c +++ b/src/gb/gprs_ns_vty.c @@ -91,11 +91,9 @@ static int config_write_ns(struct vty *vty) vty_out(vty, " nse %u remote-role %s%s", nsvc->nsei, nsvc->remote_end_is_sgsn ? "sgsn" : "bss", VTY_NEWLINE); - vty_out(vty, " nse %u compliance %s%s", - nsvc->nsei, - nsvc->compliance == GPRS_NS_TS_08_16 ? - "ts08.16" : "ts48.016", - VTY_NEWLINE); + if (nsvc->compliance == GPRS_NS_TS_48_016) + vty_out(vty, " nse %u compliance ts48.016%s", + nsvc->nsei, VTY_NEWLINE); switch (nsvc->ll) { case GPRS_NS_LL_UDP: vty_out(vty, " nse %u encapsulation udp%s", nsvc->nsei, -- 1.9.1 From jerlbeck at sysmocom.de Tue Jan 5 10:42:42 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 11:42:42 +0100 Subject: [PATCH 2/3] gprs: Remove gprs_msgb_resize_area and gprs_msgb_copy In-Reply-To: <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> References: <1447753069-17466-6-git-send-email-jerlbeck@sysmocom.de> <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451990563-4184-3-git-send-email-jerlbeck@sysmocom.de> These functions are moved to libosmocore. This commit removes the definitions and changes the names to to the corresponding libosmogb/libosmocore ones: gprs_msgb_copy -> bssgp_msgb_copy (libosmogb) gprs_msgb_resize_area -> msgb_resize_area (libosmocore) Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gprs_utils.h | 8 ++-- openbsc/src/gprs/gb_proxy.c | 8 ++-- openbsc/src/gprs/gb_proxy_patch.c | 4 +- openbsc/src/gprs/gprs_gmm.c | 2 +- openbsc/src/gprs/gprs_utils.c | 84 ------------------------------------ openbsc/tests/gbproxy/gbproxy_test.c | 2 +- 6 files changed, 13 insertions(+), 95 deletions(-) diff --git a/openbsc/include/openbsc/gprs_utils.h b/openbsc/include/openbsc/gprs_utils.h index 7af83ba..8942e40 100644 --- a/openbsc/include/openbsc/gprs_utils.h +++ b/openbsc/include/openbsc/gprs_utils.h @@ -27,9 +27,11 @@ struct msgb; -struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); -int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, - size_t old_size, size_t new_size); +char *gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars) + OSMO_DEPRECATED("Use osmo_apn_to_str instead"); +int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str) + OSMO_DEPRECATED("Use osmo_apn_from_str instead"); + /* GSM 04.08, 10.5.7.3 GPRS Timer */ int gprs_tmr_to_secs(uint8_t tmr); uint8_t gprs_secs_to_tmr_floor(int secs); diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 6cad651..7a290d3 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -486,7 +486,7 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, msgb_nsei(msg), parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); - stored_msg = gprs_msgb_copy(msg, "process_bssgp_ul"); + stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul"); msgb_enqueue(&link_info->stored_msgs, stored_msg); if (!link_info->imsi_acq_pending) { @@ -750,7 +750,7 @@ static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, { /* create a copy of the message so the old one can * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2sgsn"); + struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn"); int rc; DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n", @@ -774,7 +774,7 @@ static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer, { /* create a copy of the message so the old one can * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2peer"); + struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2peer"); int rc; DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n", @@ -1169,7 +1169,7 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg, return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg); } - msg = gprs_msgb_copy(orig_msg, "rx_sig_from_sgsn"); + msg = bssgp_msgb_copy(orig_msg, "rx_sig_from_sgsn"); gbprox_process_bssgp_dl(cfg, msg, NULL); /* Update message info */ bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c index 725a863..9c3510a 100644 --- a/openbsc/src/gprs/gb_proxy_patch.c +++ b/openbsc/src/gprs/gb_proxy_patch.c @@ -106,7 +106,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg, osmo_apn_to_str(str1, apn, apn_len)); *new_apn_ie_len = 0; - gprs_msgb_resize_area(msg, apn_ie, apn_ie_len, 0); + msgb_resize_area(msg, apn_ie, apn_ie_len, 0); } else { /* Resize the IE */ char str1[110]; @@ -123,7 +123,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg, peer->cfg->core_apn_size)); *new_apn_ie_len = peer->cfg->core_apn_size + 2; - gprs_msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size); + msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size); memcpy(apn, peer->cfg->core_apn, peer->cfg->core_apn_size); hdr->apn_len = peer->cfg->core_apn_size; } diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 115e898..5ad8fd2 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -1888,7 +1888,7 @@ static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx, * and the dynamic resolution will be the right thing * in the long run. */ - msg = gprs_msgb_copy(_msg, __func__); + msg = bssgp_msgb_copy(_msg, __func__); if (!msg) { struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg); uint8_t transaction_id = (gh->proto_discr >> 4); diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c index 8a98ae6..ee6adfc 100644 --- a/openbsc/src/gprs/gprs_utils.c +++ b/openbsc/src/gprs/gprs_utils.c @@ -29,90 +29,6 @@ #include -/* FIXME: this needs to go to libosmocore/msgb.c */ -struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name) -{ - struct libgb_msgb_cb *old_cb, *new_cb; - struct msgb *new_msg; - - new_msg = msgb_alloc(msg->data_len, name); - if (!new_msg) - return NULL; - - /* copy data */ - memcpy(new_msg->_data, msg->_data, new_msg->data_len); - - /* copy header */ - new_msg->len = msg->len; - new_msg->data += msg->data - msg->_data; - new_msg->head += msg->head - msg->_data; - new_msg->tail += msg->tail - msg->_data; - - if (msg->l1h) - new_msg->l1h = new_msg->_data + (msg->l1h - msg->_data); - if (msg->l2h) - new_msg->l2h = new_msg->_data + (msg->l2h - msg->_data); - if (msg->l3h) - new_msg->l3h = new_msg->_data + (msg->l3h - msg->_data); - if (msg->l4h) - new_msg->l4h = new_msg->_data + (msg->l4h - msg->_data); - - /* copy GB specific data */ - old_cb = LIBGB_MSGB_CB(msg); - new_cb = LIBGB_MSGB_CB(new_msg); - - if (old_cb->bssgph) - new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data); - if (old_cb->llch) - new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data); - - /* bssgp_cell_id is a pointer into the old msgb, so we need to make - * it a pointer into the new msgb */ - if (old_cb->bssgp_cell_id) - new_cb->bssgp_cell_id = new_msg->_data + - (old_cb->bssgp_cell_id - msg->_data); - new_cb->nsei = old_cb->nsei; - new_cb->bvci = old_cb->bvci; - new_cb->tlli = old_cb->tlli; - - return new_msg; -} - -/* TODO: Move this to libosmocore/msgb.c */ -int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, - size_t old_size, size_t new_size) -{ - int rc; - uint8_t *rest = area + old_size; - int rest_len = msg->len - old_size - (area - msg->data); - int delta_size = (int)new_size - (int)old_size; - - if (delta_size == 0) - return 0; - - if (delta_size > 0) { - rc = msgb_trim(msg, msg->len + delta_size); - if (rc < 0) - return rc; - } - - memmove(area + new_size, area + old_size, rest_len); - - if (msg->l1h >= rest) - msg->l1h += delta_size; - if (msg->l2h >= rest) - msg->l2h += delta_size; - if (msg->l3h >= rest) - msg->l3h += delta_size; - if (msg->l4h >= rest) - msg->l4h += delta_size; - - if (delta_size < 0) - msgb_trim(msg, msg->len + delta_size); - - return 0; -} - /* GSM 04.08, 10.5.7.3 GPRS Timer */ int gprs_tmr_to_secs(uint8_t tmr) { diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index 97aa32f..d5284a9 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -1064,7 +1064,7 @@ int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg) if (received_messages) { struct msgb *msg_copy; - msg_copy = gprs_msgb_copy(msg, "received_messages"); + msg_copy = bssgp_msgb_copy(msg, "received_messages"); llist_add_tail(&msg_copy->list, received_messages); } -- 1.9.1 From jerlbeck at sysmocom.de Tue Jan 5 10:42:40 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 11:42:40 +0100 Subject: Patch openbsc to use the moved and renamed functions In-Reply-To: <1447753069-17466-6-git-send-email-jerlbeck@sysmocom.de> References: <1447753069-17466-6-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> Hi, this patch set expects that the following patches have been applied to the libosmocore project: - msgb: Add msgb_resize_area and msgb_copy - gb: Add bssgp_msgb_copy function - gsm: Add APN conversion functions Jacob [PATCH 1/3] gprs: Remove gprs_apn_to_str and gprs_str_to_apn [PATCH 2/3] gprs: Remove gprs_msgb_resize_area and gprs_msgb_copy [PATCH 3/3] sgsn: Consolidate gprs_apn2str with osmo_apn_to_str ====== openbsc/include/openbsc/gprs_utils.h | 10 +-- openbsc/src/gprs/gb_proxy.c | 8 +- openbsc/src/gprs/gb_proxy_patch.c | 11 +-- openbsc/src/gprs/gb_proxy_vty.c | 6 +- openbsc/src/gprs/gprs_gmm.c | 2 +- openbsc/src/gprs/gprs_sgsn.c | 4 +- openbsc/src/gprs/gprs_subscriber.c | 5 +- openbsc/src/gprs/gprs_utils.c | 146 ----------------------------------- openbsc/src/gprs/gtphub.c | 4 +- openbsc/src/gprs/sgsn_cdr.c | 5 +- openbsc/src/gprs/sgsn_vty.c | 22 +----- openbsc/tests/gbproxy/gbproxy_test.c | 15 ++-- openbsc/tests/gprs/gprs_test.c | 29 +++---- openbsc/tests/gtphub/Makefile.am | 1 + openbsc/tests/sgsn/sgsn_test.c | 13 ++-- 15 files changed, 63 insertions(+), 218 deletions(-) From jerlbeck at sysmocom.de Tue Jan 5 10:42:41 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 11:42:41 +0100 Subject: [PATCH 1/3] gprs: Remove gprs_apn_to_str and gprs_str_to_apn In-Reply-To: <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> References: <1447753069-17466-6-git-send-email-jerlbeck@sysmocom.de> <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451990563-4184-2-git-send-email-jerlbeck@sysmocom.de> These functions are moved to libosmocore. This commit removes the definitions and changes the names to the corresponding libosmogsm ones: gprs_str_to_apn -> osmo_apn_from_str gprs_apn_to_str -> osmo_apn_to_str Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gprs_utils.h | 4 +-- openbsc/src/gprs/gb_proxy_patch.c | 7 ++-- openbsc/src/gprs/gb_proxy_vty.c | 6 ++-- openbsc/src/gprs/gprs_sgsn.c | 4 +-- openbsc/src/gprs/gprs_subscriber.c | 5 +-- openbsc/src/gprs/gprs_utils.c | 62 ------------------------------------ openbsc/src/gprs/gtphub.c | 4 +-- openbsc/src/gprs/sgsn_cdr.c | 5 +-- openbsc/src/gprs/sgsn_vty.c | 2 +- openbsc/tests/gbproxy/gbproxy_test.c | 13 ++++---- openbsc/tests/gprs/gprs_test.c | 29 +++++++++-------- openbsc/tests/gtphub/Makefile.am | 1 + openbsc/tests/sgsn/sgsn_test.c | 13 ++++---- 13 files changed, 49 insertions(+), 106 deletions(-) diff --git a/openbsc/include/openbsc/gprs_utils.h b/openbsc/include/openbsc/gprs_utils.h index 6880e05..7af83ba 100644 --- a/openbsc/include/openbsc/gprs_utils.h +++ b/openbsc/include/openbsc/gprs_utils.h @@ -23,15 +23,13 @@ #include #include +#include struct msgb; struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, size_t old_size, size_t new_size); -char *gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars); -int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str); - /* GSM 04.08, 10.5.7.3 GPRS Timer */ int gprs_tmr_to_secs(uint8_t tmr); uint8_t gprs_secs_to_tmr_floor(int secs); diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c index c1d2497..725a863 100644 --- a/openbsc/src/gprs/gb_proxy_patch.c +++ b/openbsc/src/gprs/gb_proxy_patch.c @@ -28,6 +28,7 @@ #include #include +#include #include /* patch RA identifier in place */ @@ -102,7 +103,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg, LOGP(DGPRS, LOGL_DEBUG, "Patching %s to SGSN: Removing APN '%s'\n", log_text, - gprs_apn_to_str(str1, apn, apn_len)); + osmo_apn_to_str(str1, apn, apn_len)); *new_apn_ie_len = 0; gprs_msgb_resize_area(msg, apn_ie, apn_ie_len, 0); @@ -117,8 +118,8 @@ static void gbproxy_patch_apn_ie(struct msgb *msg, "Patching %s to SGSN: " "Replacing APN '%s' -> '%s'\n", log_text, - gprs_apn_to_str(str1, apn, apn_len), - gprs_apn_to_str(str2, peer->cfg->core_apn, + osmo_apn_to_str(str1, apn, apn_len), + osmo_apn_to_str(str2, peer->cfg->core_apn, peer->cfg->core_apn_size)); *new_apn_ie_len = peer->cfg->core_apn_size + 2; diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c index 933b6b0..bf11a6d 100644 --- a/openbsc/src/gprs/gb_proxy_vty.c +++ b/openbsc/src/gprs/gb_proxy_vty.c @@ -29,10 +29,10 @@ #include #include +#include #include #include -#include #include #include @@ -107,7 +107,7 @@ static int config_write_gbproxy(struct vty *vty) if (g_cfg->core_apn_size > 0) { char str[500] = {0}; vty_out(vty, " core-access-point-name %s%s", - gprs_apn_to_str(str, g_cfg->core_apn, + osmo_apn_to_str(str, g_cfg->core_apn, g_cfg->core_apn_size), VTY_NEWLINE); } else { @@ -279,7 +279,7 @@ static int set_core_apn(struct vty *vty, const char *apn) g_cfg->core_apn = talloc_realloc_size(NULL, g_cfg->core_apn, apn_len + 1); g_cfg->core_apn_size = - gprs_str_to_apn(g_cfg->core_apn, apn_len + 1, apn); + osmo_apn_from_str(g_cfg->core_apn, apn_len + 1, apn); } return CMD_SUCCESS; diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index c4dc9d7..b770a3a 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,6 @@ #include #include #include -#include #include #include "openbsc/gprs_llc.h" @@ -650,7 +650,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, return NULL; } - gprs_apn_to_str(req_apn_str, + osmo_apn_to_str(req_apn_str, TLVP_VAL(tp, GSM48_IE_GSM_APN), TLVP_LEN(tp, GSM48_IE_GSM_APN)); diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 3467293..8f5dc9d 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -27,10 +27,11 @@ #include #include #include -#include #include +#include + #include #include @@ -328,7 +329,7 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, OSMO_ASSERT(pdp_data != NULL); pdp_data->pdp_type = pdp_info->pdp_type; - gprs_apn_to_str(pdp_data->apn_str, + osmo_apn_to_str(pdp_data->apn_str, pdp_info->apn_enc, pdp_info->apn_enc_len); memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len); pdp_data->qos_subscribed_len = pdp_info->qos_enc_len; diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c index ad479db..8a98ae6 100644 --- a/openbsc/src/gprs/gprs_utils.c +++ b/openbsc/src/gprs/gprs_utils.c @@ -113,68 +113,6 @@ int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, return 0; } -/* TODO: Move these conversion functions to a utils file. */ -/* TODO: consolidate with gprs_apn2str(). */ -/** memmove apn_enc to out_str, replacing the length octets in apn_enc with '.' - * (omitting the first one) and terminating with a '\0'. - * out_str needs to have rest_chars amount of bytes or 1 whatever is bigger. - */ -char * gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars) -{ - char *str = out_str; - - while (rest_chars > 0 && apn_enc[0]) { - size_t label_size = apn_enc[0]; - if (label_size + 1 > rest_chars) - return NULL; - - memmove(str, apn_enc + 1, label_size); - str += label_size; - rest_chars -= label_size + 1; - apn_enc += label_size + 1; - - if (rest_chars) - *(str++) = '.'; - } - str[0] = '\0'; - - return out_str; -} - -int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str) -{ - uint8_t *last_len_field; - int len; - - /* Can we even write the length field to the output? */ - if (max_len == 0) - return -1; - - /* Remember where we need to put the length once we know it */ - last_len_field = apn_enc; - len = 1; - apn_enc += 1; - - while (str[0]) { - if (len >= max_len) - return -1; - - if (str[0] == '.') { - *last_len_field = (apn_enc - last_len_field) - 1; - last_len_field = apn_enc; - } else { - *apn_enc = str[0]; - } - apn_enc += 1; - str += 1; - len += 1; - } - - *last_len_field = (apn_enc - last_len_field) - 1; - - return len; -} - /* GSM 04.08, 10.5.7.3 GPRS Timer */ int gprs_tmr_to_secs(uint8_t tmr) { diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c index f26a56a..09175eb 100644 --- a/openbsc/src/gprs/gtphub.c +++ b/openbsc/src/gprs/gtphub.c @@ -34,13 +34,13 @@ #include #include -#include #include #include #include #include #include +#include static const int GTPH_GC_TICK_SECONDS = 1; @@ -498,7 +498,7 @@ static int get_ie_apn_str(union gtpie_member *ie[], const char **apn_str) len = sizeof(apn_buf) - 1; apn_buf[len] = '\0'; - *apn_str = gprs_apn_to_str(apn_buf, (uint8_t*)apn_buf, len); + *apn_str = osmo_apn_to_str(apn_buf, (uint8_t*)apn_buf, len); if (!(*apn_str)) { LOG(LOGL_ERROR, "APN IE: present but cannot be decoded: %s\n", osmo_hexdump((uint8_t*)apn_buf, len)); diff --git a/openbsc/src/gprs/sgsn_cdr.c b/openbsc/src/gprs/sgsn_cdr.c index d0cb712..5d16249 100644 --- a/openbsc/src/gprs/sgsn_cdr.c +++ b/openbsc/src/gprs/sgsn_cdr.c @@ -20,11 +20,12 @@ #include #include -#include #include #include +#include + #include #include @@ -145,7 +146,7 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev, if (pdp->lib) { - gprs_apn_to_str(apni, pdp->lib->apn_use.v, pdp->lib->apn_use.l); + osmo_apn_to_str(apni, pdp->lib->apn_use.v, pdp->lib->apn_use.l); inet_ntop(AF_INET, &pdp->lib->hisaddr0.s_addr, ggsn_addr, sizeof(ggsn_addr)); extract_eua(&pdp->lib->eua, eua_addr); } diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 3f61163..706c9ea 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -110,7 +110,7 @@ DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)") #define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */ -/* TODO: consolidate with gprs_apn_to_str(). */ +/* TODO: consolidate with osmo_apn_to_str(). */ /** Copy apn to a static buffer, replacing the length octets in apn_enc with '.' * and terminating with a '\0'. Return the static buffer. * len: the length of the encoded APN (which has no terminating zero). diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index 0ba827f..97aa32f 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1660,7 +1661,7 @@ static void test_gbproxy_ra_patching() gbcfg.core_mcc = 123; gbcfg.core_mnc = 456; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 0; configure_sgsn_peer(&sgsn_peer); @@ -2001,7 +2002,7 @@ static void test_gbproxy_ptmsi_assignment() gbcfg.core_mcc = 0; gbcfg.core_mnc = 0; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 0; configure_sgsn_peer(&sgsn_peer); @@ -2235,7 +2236,7 @@ static void test_gbproxy_ptmsi_patching() gbcfg.core_mcc = 123; gbcfg.core_mnc = 456; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 1; configure_sgsn_peer(&sgsn_peer); @@ -2554,7 +2555,7 @@ static void test_gbproxy_ptmsi_patching_bad_cases() gbcfg.core_mcc = 123; gbcfg.core_mnc = 456; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 1; configure_sgsn_peer(&sgsn_peer); @@ -2738,7 +2739,7 @@ static void test_gbproxy_imsi_acquisition() gbcfg.core_mcc = 123; gbcfg.core_mnc = 456; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 1; gbcfg.acquire_imsi = 1; @@ -3064,7 +3065,7 @@ static void test_gbproxy_secondary_sgsn() gbcfg.core_mcc = 123; gbcfg.core_mnc = 456; gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); + gbcfg.core_apn_size = osmo_apn_from_str(gbcfg.core_apn, 100, "foo.bar"); gbcfg.patch_ptmsi = 1; gbcfg.acquire_imsi = 1; diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index c78b98a..20b0bb4 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -10,6 +10,7 @@ #include #include +#include #define ASSERT_FALSE(x) if (x) { printf("Should have returned false.\n"); abort(); } #define ASSERT_TRUE(x) if (!x) { printf("Should have returned true.\n"); abort(); } @@ -59,7 +60,7 @@ static void apn_round_trip(const uint8_t *input, size_t len, const char *wanted_ int enc_len; /* decode and verify we have what we want */ - out_str = gprs_apn_to_str(output, input, len); + out_str = osmo_apn_to_str(output, input, len); OSMO_ASSERT(out_str); OSMO_ASSERT(out_str == &output[0]); OSMO_ASSERT(strlen(out_str) == strlen(wanted_output)); @@ -67,11 +68,11 @@ static void apn_round_trip(const uint8_t *input, size_t len, const char *wanted_ /* encode and verify it */ if (len != 0) { - enc_len = gprs_str_to_apn(encoded, ARRAY_SIZE(encoded), wanted_output); + enc_len = osmo_apn_from_str(encoded, ARRAY_SIZE(encoded), wanted_output); OSMO_ASSERT(enc_len == len); OSMO_ASSERT(memcmp(encoded, input, enc_len) == 0); } else { - enc_len = gprs_str_to_apn(encoded, 0, wanted_output); + enc_len = osmo_apn_from_str(encoded, 0, wanted_output); OSMO_ASSERT(enc_len == -1); } } @@ -86,27 +87,27 @@ static void test_gsm_03_03_apn(void) int enc_len; memcpy(output, ref, ARRAY_SIZE(output)); - enc_len = gprs_str_to_apn(output, 0, ""); + enc_len = osmo_apn_from_str(output, 0, ""); OSMO_ASSERT(enc_len == -1); OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0); memcpy(output, ref, ARRAY_SIZE(output)); - enc_len = gprs_str_to_apn(output, 0, "foo"); + enc_len = osmo_apn_from_str(output, 0, "foo"); OSMO_ASSERT(enc_len == -1); OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0); memcpy(output, ref, ARRAY_SIZE(output)); - enc_len = gprs_str_to_apn(output, 1, "foo"); + enc_len = osmo_apn_from_str(output, 1, "foo"); OSMO_ASSERT(enc_len == -1); OSMO_ASSERT(memcmp(ref + 1, output + 1, ARRAY_SIZE(ref) - 1) == 0); memcpy(output, ref, ARRAY_SIZE(output)); - enc_len = gprs_str_to_apn(output, 2, "foo"); + enc_len = osmo_apn_from_str(output, 2, "foo"); OSMO_ASSERT(enc_len == -1); OSMO_ASSERT(memcmp(ref + 2, output + 2, ARRAY_SIZE(ref) - 2) == 0); memcpy(output, ref, ARRAY_SIZE(output)); - enc_len = gprs_str_to_apn(output, 3, "foo"); + enc_len = osmo_apn_from_str(output, 3, "foo"); OSMO_ASSERT(enc_len == -1); OSMO_ASSERT(memcmp(ref + 3, output + 3, ARRAY_SIZE(ref) - 3) == 0); } @@ -130,7 +131,7 @@ static void test_gsm_03_03_apn(void) uint8_t input[] = { 0x1, 65 }; const char *output = "A"; apn_round_trip(input, ARRAY_SIZE(input), output); - OSMO_ASSERT(gprs_apn_to_str(NULL, input, ARRAY_SIZE(input) - 1) == NULL); + OSMO_ASSERT(osmo_apn_to_str(NULL, input, ARRAY_SIZE(input) - 1) == NULL); } { @@ -138,11 +139,11 @@ static void test_gsm_03_03_apn(void) const char *output = "ABC.Zz"; char tmp[strlen(output) + 1]; apn_round_trip(input, ARRAY_SIZE(input), output); - OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 1) == NULL); - OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 2) == NULL); - OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 4) == NULL); - OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 5) == NULL); - OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 6) == NULL); + OSMO_ASSERT(osmo_apn_to_str(tmp, input, ARRAY_SIZE(input) - 1) == NULL); + OSMO_ASSERT(osmo_apn_to_str(tmp, input, ARRAY_SIZE(input) - 2) == NULL); + OSMO_ASSERT(osmo_apn_to_str(tmp, input, ARRAY_SIZE(input) - 4) == NULL); + OSMO_ASSERT(osmo_apn_to_str(tmp, input, ARRAY_SIZE(input) - 5) == NULL); + OSMO_ASSERT(osmo_apn_to_str(tmp, input, ARRAY_SIZE(input) - 6) == NULL); } } diff --git a/openbsc/tests/gtphub/Makefile.am b/openbsc/tests/gtphub/Makefile.am index dcb7211..7599119 100644 --- a/openbsc/tests/gtphub/Makefile.am +++ b/openbsc/tests/gtphub/Makefile.am @@ -20,5 +20,6 @@ gtphub_test_LDADD = \ $(top_builddir)/src/gprs/gtphub.o \ $(top_builddir)/src/gprs/gprs_utils.o \ $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ -lgtp -lrt diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 859223f..5df7688 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -31,7 +31,8 @@ #include -#include +#include + #include #include @@ -1957,7 +1958,7 @@ static void test_ggsn_selection(void) /* Resolve GGSNs */ tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn"); + osmo_apn_from_str(apn_enc, sizeof(apn_enc), "Test.Apn"); ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); OSMO_ASSERT(ggc != NULL); @@ -1965,7 +1966,7 @@ static void test_ggsn_selection(void) OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0); tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn"); + osmo_apn_from_str(apn_enc, sizeof(apn_enc), "Other.Apn"); ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); OSMO_ASSERT(ggc != NULL); @@ -1991,7 +1992,7 @@ static void test_ggsn_selection(void) tp.lv[GSM48_IE_GSM_APN].val = apn_enc; tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar"); + osmo_apn_from_str(apn_enc, sizeof(apn_enc), "Foo.Bar"); ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); OSMO_ASSERT(ggc == NULL); @@ -2008,7 +2009,7 @@ static void test_ggsn_selection(void) strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1); tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn"); + osmo_apn_from_str(apn_enc, sizeof(apn_enc), "Test.Apn"); ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); OSMO_ASSERT(ggc != NULL); @@ -2016,7 +2017,7 @@ static void test_ggsn_selection(void) OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0); tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn"); + osmo_apn_from_str(apn_enc, sizeof(apn_enc), "Other.Apn"); ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); OSMO_ASSERT(ggc == NULL); -- 1.9.1 From jerlbeck at sysmocom.de Tue Jan 5 10:42:43 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 11:42:43 +0100 Subject: [PATCH 3/3] sgsn: Consolidate gprs_apn2str with osmo_apn_to_str In-Reply-To: <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> References: <1447753069-17466-6-git-send-email-jerlbeck@sysmocom.de> <1451990563-4184-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1451990563-4184-4-git-send-email-jerlbeck@sysmocom.de> This commit replaces the implementation of gprs_apn2str by a call to osmo_apn_to_str. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/sgsn_vty.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 706c9ea..384f1f8 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -40,6 +40,8 @@ #include #include +#include + #include #include @@ -110,7 +112,6 @@ DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)") #define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */ -/* TODO: consolidate with osmo_apn_to_str(). */ /** Copy apn to a static buffer, replacing the length octets in apn_enc with '.' * and terminating with a '\0'. Return the static buffer. * len: the length of the encoded APN (which has no terminating zero). @@ -118,25 +119,8 @@ DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)") static char *gprs_apn2str(uint8_t *apn, unsigned int len) { static char apnbuf[GSM48_MAX_APN_LEN+1]; - unsigned int i = 0; - - if (!apn) - return ""; - - if (len > sizeof(apnbuf)-1) - len = sizeof(apnbuf)-1; - - memcpy(apnbuf, apn, len); - apnbuf[len] = '\0'; - - /* replace the domain name step sizes with dots */ - while (i < len) { - unsigned int step = apnbuf[i]; - apnbuf[i] = '.'; - i += step+1; - } - return apnbuf+1; + return osmo_apn_to_str(apnbuf, apn, len); } char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len) -- 1.9.1 From nhofmeyr at sysmocom.de Tue Jan 5 12:51:59 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Tue, 5 Jan 2016 13:51:59 +0100 Subject: FYI: gtphub merged In-Reply-To: <20151215122631.GC13429@dub5> References: <20151203105255.GB1698@dub5> <1608075646.11725224.1449146301692.JavaMail.zimbra@kvk.uni-obuda.hu> <20151207101219.GA2387@dub5> <566EABF5.4010405@alumni.ntnu.no> <20151215122631.GC13429@dub5> Message-ID: <20160105125159.GA7374@dub6> On Tue, Dec 15, 2015 at 01:26:31PM +0100, Neels Hofmeyr wrote: > On Mon, Dec 14, 2015 at 12:45:57PM +0100, Suraev wrote: > > Hi. > > > > Could be also nice if you add couple of lines to > > http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS > > Thanks for the hint! There had also been plans for an SVG to provide an > overview. Will probably follow next week or so. ...turns out we're still too busy. I hope to follow up on this "soonish". Feel free to bump! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From jerlbeck at sysmocom.de Tue Jan 5 12:53:18 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Jan 2016 13:53:18 +0100 Subject: [PATCH 2/2] logging: Remember the target we found In-Reply-To: <1450708780-9785-2-git-send-email-holger@freyther.de> References: <1450708780-9785-1-git-send-email-holger@freyther.de> <1450708780-9785-2-git-send-email-holger@freyther.de> Message-ID: <568BBCBE.2090709@sysmocom.de> Hi, On 21.12.2015 15:39, Holger Hans Peter Freyther wrote: > From: Holger Hans Peter Freyther > [...] > > /* use the above macros */ > void logp2(int subsys, unsigned int level, const char *file, > - int line, int cont, const char *format, ...) > - __attribute__ ((format (printf, 6, 7))); > + int line, int cont, struct log_target *iniial_target, > + const char *format, ...) > + __attribute__ ((format (printf, 7, 8))); Note that this will break openbsc/src/ipaccess/ipaccess-proxy.c. Jacob -- - Jacob Erlbeck http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From holger at freyther.de Thu Jan 7 06:58:14 2016 From: holger at freyther.de (Holger Freyther) Date: Thu, 7 Jan 2016 07:58:14 +0100 Subject: How to test the debian packages? Message-ID: Good Morning, Max has brought up the topic of somehow testing the debian packages and I wonder what aspects we need to test it. Ideally we would test: (a) Building a new version of everything against the last packages we have built to find wrong minimum versions. (b) Create source packages and build everything. (c) Try to upgrade services and check something is respawned and the config file is compatible. (a) is a complicated mess. We do add new interfaces, versions to the development version of libraries and we don't want to bump the SO_VERSION and such until we make a release. So this item will always break. (b) Is quite easy. When making a release we should open the changelog with version+1 and not being released and then make nightly source packages and upload them to the OpenSUSE build service and see how it fails. (c) Is possible but a bit tricky again. We need to do this for each service (e.g. nitb and bsc share the same VTY, OML, RSL port and are mutual exclusive). Max is probably aiming for (b) and I think it is not that needed. I tend to make releases and build packages and the breakage is quite small from release to release. I think there would be real value in (c) but that requires some work that we will probably not have time for in Q1. holger From suraev at alumni.ntnu.no Thu Jan 7 09:59:25 2016 From: suraev at alumni.ntnu.no (Suraev) Date: Thu, 7 Jan 2016 10:59:25 +0100 Subject: How to test the debian packages? In-Reply-To: References: Message-ID: <568E36FD.4040809@alumni.ntnu.no> Hi. I think we can reuse some of the Debian tools: https://piuparts.debian.org/ Other possible tests are running dpkg-buildpackage as part of jenkins test suite and maybe also running lintian against the results to maintain package quality. cheers, Max. From suraev at alumni.ntnu.no Mon Jan 11 22:16:35 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?4pit?=) Date: Mon, 11 Jan 2016 23:16:35 +0100 Subject: Using Gerrit for libosmocore/lib../OpenBSC? In-Reply-To: <74424E06-4311-49A1-B5D3-BCE1DE8D8A7B@freyther.de> References: <74424E06-4311-49A1-B5D3-BCE1DE8D8A7B@freyther.de> Message-ID: <569429C3.2090103@alumni.ntnu.no> I'd like to bring up this discussion again - I think the lesser the chance for upstream to lose some contribution, the better it is. I've stumbled upon https://kallithea-scm.org/#about which does advertise code review features and in general seems like open source github. Never worked with it in real life though so I don't know if there's a catch. What do you think? cheers, Max. From laforge at gnumonks.org Tue Jan 12 15:12:00 2016 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 12 Jan 2016 16:12:00 +0100 Subject: OsmoDevCon 2016 date poll Message-ID: <20160112151200.GP1762@nataraja> Dear all, IN-Berlin has confirmed the dates in April where we could book the venue. Can those eligible + interested in attending please quickly indicate their preference at http://doodle.com/poll/if263cpxieavsqiq ? Thanks! Disclaimer: OsmoDevCon is an invitation-only event for developers with proven history of contributing to any of the Osmocom projects. The fact that there is a public poll about the scheduling of the event and/or your participation in that poll does not mean a particular applicant is invited. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." From laforge at gnumonks.org Wed Jan 13 13:35:26 2016 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 13 Jan 2016 14:35:26 +0100 Subject: OsmoDevCon 2016 date poll In-Reply-To: <20160112151200.GP1762@nataraja> References: <20160112151200.GP1762@nataraja> Message-ID: <20160113133526.GO9964@nataraja> On Tue, Jan 12, 2016 at 04:12:00PM +0100, Harald Welte wrote: > Can those eligible + interested in attending please quickly indicate > their preference at http://doodle.com/poll/if263cpxieavsqiq ? Thanks for the quick feedback. I have now chosen April 21st through April 24th, as this was acceptable to everybody participating in the poll and it has least overlap/impact on the schedule of other groups meeting at the IN-Berlin venue. So feel free to mark that date in your calendar. Further planning will follow in the next weeks. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From nhofmeyr at sysmocom.de Thu Jan 14 10:02:11 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Thu, 14 Jan 2016 11:02:11 +0100 Subject: error in Sponsored-by tag Message-ID: <20160114100211.GA1873@dub6> Hi list, during my gtphub development, I marked numerous commits as Sponsored-by: On-Waves ehi which is wrong. The ehi should have been ehf: Sponsored-by: On-Waves ehf It's in the history now, so unless we rebase kazillion of commits on openbsc master, the ehi is gonna stick. So ... why didn't any reviewer catch that a bit sooner? ;) Opinions welcome. And thanks, ?, for spotting this, at last! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Fri Jan 15 14:03:34 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 15 Jan 2016 15:03:34 +0100 Subject: [PATCH 2/2] src/stat_item.c: fix cast In-Reply-To: <80AD3955-AFB0-43AD-ACB4-8C63A025EF5B@freyther.de> References: <20151106194820.GC30339@yade.xx.vu> <1446839725-21682-1-git-send-email-alexander.huemer@xx.vu> <1446839725-21682-3-git-send-email-alexander.huemer@xx.vu> <80AD3955-AFB0-43AD-ACB4-8C63A025EF5B@freyther.de> Message-ID: > On 07 Nov 2015, at 12:30, Holger Freyther wrote: > > >> src/stat_item.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/src/stat_item.c b/src/stat_item.c >> index 0545ea0..7017523 100644 >> --- a/src/stat_item.c >> +++ b/src/stat_item.c >> @@ -81,7 +81,7 @@ struct osmo_stat_item_group *osmo_stat_item_group_alloc(void *ctx, >> size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1); >> >> /* Store offsets into the item array */ >> - group->items[item_idx] = (void *)items_size; >> + group->items[item_idx] = (struct osmo_stat_item *)items_size; > > This will silence the warning but I think we could change the code to be more direct at > the cost of recalculating the offset twice but staying with the pointers of the right type? @Jacob: ping? From holger at freyther.de Fri Jan 15 14:37:27 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 15 Jan 2016 15:37:27 +0100 Subject: [PATCH 1/2] buildsystem: follow libtoolize suggestions In-Reply-To: <20151107130732.GB26613@yade.xx.vu> References: <20151106194820.GC30339@yade.xx.vu> <1446840034-11954-1-git-send-email-alexander.huemer@xx.vu> <1446840034-11954-2-git-send-email-alexander.huemer@xx.vu> <20151107130732.GB26613@yade.xx.vu> Message-ID: <87F1283F-6A15-4106-9CE2-B286DD99FC88@freyther.de> > On 07 Nov 2015, at 14:07, Alexander Huemer wrote: > > Hi! > > On Sat, Nov 07, 2015 at 12:45:33PM +0100, Holger Freyther wrote: >>> On 06 Nov 2015, at 21:00, Alexander Huemer wrote: >> >> Well, we don't have any m4 macros ourselves and just creating an empty directory doesn't >> look like a good idea. Have you considered asking on the libtool/autoconf list where this >> warning is coming from and what to do about it? > > Are you sure this approach is wrong? > In libosmocore the same was done in commit > b2eb83fa95b209fb01de2996a1382c944fc265fe of 2010, I actually took the > filename from there. > If you prefer I can check with the autotools people. yes, please. I mean why do we create a m4/DUMMY just to fix a suggestion by a tool? It shows that we don't have a need for this directory right now? From holger at freyther.de Fri Jan 15 14:39:19 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 15 Jan 2016 15:39:19 +0100 Subject: [PATCH 2/2] fix some format specifiers In-Reply-To: <1446840034-11954-3-git-send-email-alexander.huemer@xx.vu> References: <20151106194820.GC30339@yade.xx.vu> <1446840034-11954-1-git-send-email-alexander.huemer@xx.vu> <1446840034-11954-3-git-send-email-alexander.huemer@xx.vu> Message-ID: <327225C4-DF1F-4529-8CC0-3858C6A6C014@freyther.de> > On 06 Nov 2015, at 21:00, Alexander Huemer wrote: Dear Jacob, this seems to still apply. Could you please review and update the case on patchwork? kind regards holger > > --- > src/pcu_vty_functions.cpp | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp > index d2a3641..df24171 100644 > --- a/src/pcu_vty_functions.cpp > +++ b/src/pcu_vty_functions.cpp > @@ -22,6 +22,7 @@ > > #include > #include > +#include > #include "pcu_vty_functions.h" > #include "bts.h" > #include "gprs_ms_storage.h" > @@ -47,7 +48,7 @@ int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) > llist_for_each(ms_iter, &bts->ms_store().ms_list()) { > GprsMs *ms = ms_iter->entry(); > > - vty_out(vty, "MS TLLI=%08x, TA=%d, CS-UL=%d, CS-DL=%d, LLC=%d, " > + vty_out(vty, "MS TLLI=%08x, TA=%d, CS-UL=%d, CS-DL=%d, LLC=%zu, " > "IMSI=%s%s", > ms->tlli(), > ms->ta(), ms->current_cs_ul(), ms->current_cs_dl(), > @@ -70,9 +71,9 @@ static int show_ms(struct vty *vty, GprsMs *ms) > vty_out(vty, " Coding scheme downlink: CS-%d%s", ms->current_cs_dl(), > VTY_NEWLINE); > vty_out(vty, " MS class: %d%s", ms->ms_class(), VTY_NEWLINE); > - vty_out(vty, " LLC queue length: %d%s", ms->llc_queue()->size(), > + vty_out(vty, " LLC queue length: %zu%s", ms->llc_queue()->size(), > VTY_NEWLINE); > - vty_out(vty, " LLC queue octets: %d%s", ms->llc_queue()->octets(), > + vty_out(vty, " LLC queue octets: %zu%s", ms->llc_queue()->octets(), > VTY_NEWLINE); > if (ms->l1_meas()->have_rssi) > vty_out(vty, " RSSI: %d dBm%s", > -- > 2.6.2 > From alexander.huemer at xx.vu Fri Jan 15 15:22:01 2016 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Fri, 15 Jan 2016 16:22:01 +0100 Subject: [PATCH 1/2] buildsystem: follow libtoolize suggestions In-Reply-To: <87F1283F-6A15-4106-9CE2-B286DD99FC88@freyther.de> References: <20151106194820.GC30339@yade.xx.vu> <1446840034-11954-1-git-send-email-alexander.huemer@xx.vu> <1446840034-11954-2-git-send-email-alexander.huemer@xx.vu> <20151107130732.GB26613@yade.xx.vu> <87F1283F-6A15-4106-9CE2-B286DD99FC88@freyther.de> Message-ID: <20160115152201.GA12261@yade.xx.vu> On Fri, Jan 15, 2016 at 03:37:27PM +0100, Holger Freyther wrote: > > > On 07 Nov 2015, at 14:07, Alexander Huemer wrote: > > > > Hi! > > > > On Sat, Nov 07, 2015 at 12:45:33PM +0100, Holger Freyther wrote: > >>> On 06 Nov 2015, at 21:00, Alexander Huemer wrote: > >> > >> Well, we don't have any m4 macros ourselves and just creating an empty directory doesn't > >> look like a good idea. Have you considered asking on the libtool/autoconf list where this > >> warning is coming from and what to do about it? > > > > Are you sure this approach is wrong? > > In libosmocore the same was done in commit > > b2eb83fa95b209fb01de2996a1382c944fc265fe of 2010, I actually took the > > filename from there. > > If you prefer I can check with the autotools people. > > yes, please. I mean why do we create a m4/DUMMY just to fix a suggestion by a tool? It > shows that we don't have a need for this directory right now? As I see the situation the approach is exactly that. Adding a file that does not hurt to make the tool happy. There are no other consequences. If you prefer to keep the repository clean of files and directories that do not add functionality, that's a of course a approach as well. BTW, I asked on the freenode#autotools channel back in November, the guys there told me the same thing. Kind regards, -Alex -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: From holger at freyther.de Fri Jan 15 16:01:23 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 15 Jan 2016 17:01:23 +0100 Subject: [PATCH 1/5] log: Add log_check_level function Message-ID: <1452873687-27987-1-git-send-email-holger@freyther.de> From: Jacob Erlbeck This commit adds this predicate function which can be used to avoid the execution of code if a certain log level is not enabled. The function will only return 0 (false), if it is sure that a logging call for the same facility and level will not produce any output. This safety criterion shall ensure, that no logging output is lost due to the use of this predicate as a guard. On the other hand, even if the predicate returns != 0 (true), no logging output might get generated by a similar logging command. Note that the current implementation is not focussed on performance, which could be improved by using a lookup table instead of iterating through every target. Sponsored-by: On-Waves ehf --- include/osmocom/core/logging.h | 1 + src/logging.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index 1c159d0..290b33d 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -198,6 +198,7 @@ void logp2(int subsys, unsigned int level, const char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 6, 7))); int log_init(const struct log_info *inf, void *talloc_ctx); +int log_check_level(int subsys, unsigned int level); /* context management */ void log_reset_context(void); diff --git a/src/logging.c b/src/logging.c index 876964a..c7b1999 100644 --- a/src/logging.c +++ b/src/logging.c @@ -865,4 +865,43 @@ int log_init(const struct log_info *inf, void *ctx) return 0; } +/*! \brief Check whether a log entry will be generated. + * \returns != 0 if a log entry might get generated by at least one target */ +int log_check_level(int subsys, unsigned int level) +{ + struct log_target *tar; + + if (subsys < 0) + subsys = subsys_lib2index(subsys); + + if (subsys > osmo_log_info->num_cat) + subsys = DLGLOBAL; + + /* TODO: The following could/should be cached (update on config) */ + + llist_for_each_entry(tar, &osmo_log_target_list, entry) { + struct log_category *category; + + category = &tar->categories[subsys]; + /* subsystem is not supposed to be logged */ + if (!category->enabled) + continue; + + /* Check the global log level */ + if (tar->loglevel != 0 && level < tar->loglevel) + continue; + + /* Check the category log level */ + if (tar->loglevel == 0 && category->loglevel != 0 && + level < category->loglevel) + continue; + + /* This might get logged (ignoring filters) */ + return 1; + } + + /* We are sure, that this will not be logged. */ + return 0; +} + /*! @} */ -- 2.6.3 From holger at freyther.de Fri Jan 15 16:01:24 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 15 Jan 2016 17:01:24 +0100 Subject: [PATCH 2/5] log: Add conditional logging based on log_check_level In-Reply-To: <1452873687-27987-1-git-send-email-holger@freyther.de> References: <1452873687-27987-1-git-send-email-holger@freyther.de> Message-ID: <1452873687-27987-2-git-send-email-holger@freyther.de> From: Jacob Erlbeck Currently the LOGP/DEBUGP arguments are always evaluated even if no logging will happen at all. This can be expensive, for instance if hexdumps or pretty printed object names are generated. This causes high base load especially on embedded devices and is a major part of CPU usage e.g. of the osmo-pcu. This commit uses the log_check_level function to avoid the evaluation of the parameters if it is known in advance, that no logging entry will be generated. Sponsored-by: On-Waves ehf --- include/osmocom/core/logging.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index 290b33d..e51487b 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -19,8 +19,18 @@ #define DEBUG #ifdef DEBUG -#define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args) -#define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args) +#define DEBUGP(ss, fmt, args...) \ + do { \ + if (log_check_level(ss, LOGL_DEBUG)) \ + logp(ss, __FILE__, __LINE__, 0, fmt, ## args); \ + } while(0) + +#define DEBUGPC(ss, fmt, args...) \ + do { \ + if (log_check_level(ss, LOGL_DEBUG)) \ + logp(ss, __FILE__, __LINE__, 1, fmt, ## args); \ + } while(0) + #else #define DEBUGP(xss, fmt, args...) #define DEBUGPC(ss, fmt, args...) @@ -39,7 +49,10 @@ void logp(int subsys, const char *file, int line, int cont, const char *format, * \param[in] args variable argument list */ #define LOGP(ss, level, fmt, args...) \ - logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args) + do { \ + if (log_check_level(ss, level)) \ + logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args); \ + } while(0) /*! \brief Continue a log message through the Osmocom logging framework * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) @@ -48,7 +61,10 @@ void logp(int subsys, const char *file, int line, int cont, const char *format, * \param[in] args variable argument list */ #define LOGPC(ss, level, fmt, args...) \ - logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args) + do { \ + if (log_check_level(ss, level)) \ + logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args); \ + } while(0) /*! \brief different log levels */ #define LOGL_DEBUG 1 /*!< \brief debugging information */ -- 2.6.3 From holger at freyther.de Fri Jan 15 16:01:26 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 15 Jan 2016 17:01:26 +0100 Subject: [PATCH 4/5] logging: Remove some code duplication In-Reply-To: <1452873687-27987-1-git-send-email-holger@freyther.de> References: <1452873687-27987-1-git-send-email-holger@freyther.de> Message-ID: <1452873687-27987-4-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther Extract the mapping of the subsystem number and the checking for the loglevel to a inline method that is shared between the new and old. --- src/logging.c | 74 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/logging.c b/src/logging.c index c7b1999..7db7101 100644 --- a/src/logging.c +++ b/src/logging.c @@ -310,35 +310,52 @@ err: target->output(target, level, buf); } -/*! \brief vararg version of logging function */ -void osmo_vlogp(int subsys, int level, const char *file, int line, - int cont, const char *format, va_list ap) +static inline int map_subsys(int subsys) { - struct log_target *tar; - if (subsys < 0) subsys = subsys_lib2index(subsys); if (subsys > osmo_log_info->num_cat) subsys = DLGLOBAL; + return subsys; +} + +static inline int check_log_to_target(struct log_target *tar, int subsys, int level) +{ + struct log_category *category; + + category = &tar->categories[subsys]; + + /* subsystem is not supposed to be logged */ + if (!category->enabled) + return 0; + + /* Check the global log level */ + if (tar->loglevel != 0 && level < tar->loglevel) + return 0; + + /* Check the category log level */ + if (tar->loglevel == 0 && category->loglevel != 0 && + level < category->loglevel) + return 0; + + /* TODO: Check the filter/selector too? */ + return 1; +} + +/*! \brief vararg version of logging function */ +void osmo_vlogp(int subsys, int level, const char *file, int line, + int cont, const char *format, va_list ap) +{ + struct log_target *tar; + + subsys = map_subsys(subsys); llist_for_each_entry(tar, &osmo_log_target_list, entry) { - struct log_category *category; int output = 0; va_list bp; - category = &tar->categories[subsys]; - /* subsystem is not supposed to be logged */ - if (!category->enabled) - continue; - - /* Check the global log level */ - if (tar->loglevel != 0 && level < tar->loglevel) - continue; - - /* Check the category log level */ - if (tar->loglevel == 0 && category->loglevel != 0 && - level < category->loglevel) + if (!check_log_to_target(tar, subsys, level)) continue; /* Apply filters here... if that becomes messy we will @@ -871,29 +888,12 @@ int log_check_level(int subsys, unsigned int level) { struct log_target *tar; - if (subsys < 0) - subsys = subsys_lib2index(subsys); - - if (subsys > osmo_log_info->num_cat) - subsys = DLGLOBAL; + subsys = map_subsys(subsys); /* TODO: The following could/should be cached (update on config) */ llist_for_each_entry(tar, &osmo_log_target_list, entry) { - struct log_category *category; - - category = &tar->categories[subsys]; - /* subsystem is not supposed to be logged */ - if (!category->enabled) - continue; - - /* Check the global log level */ - if (tar->loglevel != 0 && level < tar->loglevel) - continue; - - /* Check the category log level */ - if (tar->loglevel == 0 && category->loglevel != 0 && - level < category->loglevel) + if (!check_log_to_target(tar, subsys, level)) continue; /* This might get logged (ignoring filters) */ -- 2.6.3 From holger at freyther.de Fri Jan 15 16:01:25 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 15 Jan 2016 17:01:25 +0100 Subject: [PATCH 3/5] log/test: Extend test case for log_check_level In-Reply-To: <1452873687-27987-1-git-send-email-holger@freyther.de> References: <1452873687-27987-1-git-send-email-holger@freyther.de> Message-ID: <1452873687-27987-3-git-send-email-holger@freyther.de> From: Jacob Erlbeck This commit adds OSMO_ASSERTs for mandatory conditions related to log_check_level, and fprintfs for optional conditions, since it is always safe for log_check_level to return != 0. Sponsored-by: On-Waves ehf --- tests/logging/logging_test.c | 10 ++++++++++ tests/logging/logging_test.err | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/logging/logging_test.c b/tests/logging/logging_test.c index b263f90..3c8bac4 100644 --- a/tests/logging/logging_test.c +++ b/tests/logging/logging_test.c @@ -78,16 +78,26 @@ int main(int argc, char **argv) log_parse_category_mask(stderr_target, "DRLL:DCC"); log_parse_category_mask(stderr_target, "DRLL"); DEBUGP(DCC, "You should not see this\n"); + if (log_check_level(DMM, LOGL_DEBUG) != 0) + fprintf(stderr, "log_check_level did not catch this case\n"); log_parse_category_mask(stderr_target, "DRLL:DCC"); DEBUGP(DRLL, "You should see this\n"); + OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG) != 0); DEBUGP(DCC, "You should see this\n"); + OSMO_ASSERT(log_check_level(DCC, LOGL_DEBUG) != 0); DEBUGP(DMM, "You should not see this\n"); + if (log_check_level(DMM, LOGL_DEBUG) != 0) + fprintf(stderr, "log_check_level did not catch this case\n"); + OSMO_ASSERT(filter_called == 0); log_set_all_filter(stderr_target, 0); DEBUGP(DRLL, "You should not see this and filter is called\n"); OSMO_ASSERT(filter_called == 1); + if (log_check_level(DRLL, LOGL_DEBUG) != 0) + fprintf(stderr, + "log_check_level did not catch this case (filter)\n"); return 0; } diff --git a/tests/logging/logging_test.err b/tests/logging/logging_test.err index b59d2e8..c3b67cc 100644 --- a/tests/logging/logging_test.err +++ b/tests/logging/logging_test.err @@ -1,3 +1,3 @@ You should see this You should see this - \ No newline at end of file +log_check_level did not catch this case (filter) -- 2.6.3 From holger at freyther.de Fri Jan 15 16:01:27 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 15 Jan 2016 17:01:27 +0100 Subject: [PATCH 5/5] logging: Move the filter check up as well In-Reply-To: <1452873687-27987-1-git-send-email-holger@freyther.de> References: <1452873687-27987-1-git-send-email-holger@freyther.de> Message-ID: <1452873687-27987-5-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther There doesn't seem to be a reason not to check the filter. Update and extend the test. Currently the filter function will be called once for the log check and once for the output of it. --- src/logging.c | 20 +++++++++----------- tests/logging/logging_test.c | 19 +++++++++++++------ tests/logging/logging_test.err | 3 ++- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/logging.c b/src/logging.c index 7db7101..1c9c663 100644 --- a/src/logging.c +++ b/src/logging.c @@ -339,6 +339,15 @@ static inline int check_log_to_target(struct log_target *tar, int subsys, int le level < category->loglevel) return 0; + /* Apply filters here... if that becomes messy we will + * need to put filters in a list and each filter will + * say stop, continue, output */ + if ((tar->filter_map & LOG_FILTER_ALL) != 0) + return 1; + + if (osmo_log_info->filter_fn) + return osmo_log_info->filter_fn(&log_context, tar); + /* TODO: Check the filter/selector too? */ return 1; } @@ -358,17 +367,6 @@ void osmo_vlogp(int subsys, int level, const char *file, int line, if (!check_log_to_target(tar, subsys, level)) continue; - /* Apply filters here... if that becomes messy we will - * need to put filters in a list and each filter will - * say stop, continue, output */ - if ((tar->filter_map & LOG_FILTER_ALL) != 0) - output = 1; - else if (osmo_log_info->filter_fn) - output = osmo_log_info->filter_fn(&log_context, - tar); - if (!output) - continue; - /* According to the manpage, vsnprintf leaves the value of ap * in undefined state. Since _output uses vsnprintf and it may * be called several times, we have to pass a copy of ap. */ diff --git a/tests/logging/logging_test.c b/tests/logging/logging_test.c index 3c8bac4..3d1b7d8 100644 --- a/tests/logging/logging_test.c +++ b/tests/logging/logging_test.c @@ -30,6 +30,7 @@ enum { }; static int filter_called = 0; +static int select_output = 0; static const struct log_info_cat default_categories[] = { [DRLL] = { @@ -56,7 +57,7 @@ static int test_filter(const struct log_context *ctx, struct log_target *target) { filter_called += 1; /* omit everything */ - return 0; + return select_output; } const struct log_info log_info = { @@ -77,6 +78,9 @@ int main(int argc, char **argv) log_parse_category_mask(stderr_target, "DRLL:DCC"); log_parse_category_mask(stderr_target, "DRLL"); + + select_output = 0; + DEBUGP(DCC, "You should not see this\n"); if (log_check_level(DMM, LOGL_DEBUG) != 0) fprintf(stderr, "log_check_level did not catch this case\n"); @@ -87,17 +91,20 @@ int main(int argc, char **argv) DEBUGP(DCC, "You should see this\n"); OSMO_ASSERT(log_check_level(DCC, LOGL_DEBUG) != 0); DEBUGP(DMM, "You should not see this\n"); - if (log_check_level(DMM, LOGL_DEBUG) != 0) - fprintf(stderr, "log_check_level did not catch this case\n"); + OSMO_ASSERT(log_check_level(DMM, LOGL_DEBUG) == 0); OSMO_ASSERT(filter_called == 0); log_set_all_filter(stderr_target, 0); DEBUGP(DRLL, "You should not see this and filter is called\n"); OSMO_ASSERT(filter_called == 1); - if (log_check_level(DRLL, LOGL_DEBUG) != 0) - fprintf(stderr, - "log_check_level did not catch this case (filter)\n"); + OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG) == 0); + OSMO_ASSERT(filter_called == 2); + DEBUGP(DRLL, "You should not see this\n"); + OSMO_ASSERT(filter_called == 3); + select_output = 1; + DEBUGP(DRLL, "You should see this\n"); + OSMO_ASSERT(filter_called == 5); /* called twice on output */ return 0; } diff --git a/tests/logging/logging_test.err b/tests/logging/logging_test.err index c3b67cc..4891491 100644 --- a/tests/logging/logging_test.err +++ b/tests/logging/logging_test.err @@ -1,3 +1,4 @@ You should see this You should see this -log_check_level did not catch this case (filter) +You should see this + \ No newline at end of file -- 2.6.3 From holger at freyther.de Fri Jan 15 16:50:11 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 15 Jan 2016 17:50:11 +0100 Subject: [PATCH 1/7] sgsn: Remove tlli_foreign2local In-Reply-To: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: A non-text attachment was scrubbed... Name: not available Type: application/pgp-encrypted Size: 11 bytes Desc: PGP/MIME Versions Identification URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: encrypted.asc Type: application/octet-stream Size: 1386 bytes Desc: OpenPGP encrypted message URL: From holger at freyther.de Fri Jan 15 17:03:02 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 15 Jan 2016 18:03:02 +0100 Subject: [PATCH 7/7] sgsn: Re-add searching for MM ctx based on TLLI / P-TMSI matches In-Reply-To: <1451929418-32581-7-git-send-email-jerlbeck@sysmocom.de> References: <1451929418-32581-1-git-send-email-jerlbeck@sysmocom.de> <1451929418-32581-7-git-send-email-jerlbeck@sysmocom.de> Message-ID: <47FA2FFA-EFCE-4A8E-BCEC-79025B5C4331@freyther.de> > On 04 Jan 2016, at 18:43, Jacob Erlbeck wrote: Dear Jacob, > diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c > index 6e7e5f1..212c7d7 100644 > --- a/openbsc/src/gprs/gprs_gmm.c > +++ b/openbsc/src/gprs/gprs_gmm.c > @@ -1172,13 +1172,33 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, > * if the TLLI matches foreign_tlli (P-TMSI). Note that this > * is an optimization to avoid the RA reject (impl detached) > * below, which will cause a new attach cycle. */ > - } > - the todo above reads: /* TODO: Check if there is an MM CTX with old_ra_id and * the P-TMSI (if given, reguired for UMTS) or as last resort * if the TLLI matches foreign_tlli (P-TMSI). Note that this * is an optimization to avoid the RA reject (impl detached) * below, which will cause a new attach cycle. */ I think this todo is addressed with sgsn_mm_ctx_by_tlli_and_ptmsi? Can the comment be removed? What about the test? Do we have one that gets the "XID RESET" we expect? holger From omar.ramadan at berkeley.edu Fri Jan 15 19:50:47 2016 From: omar.ramadan at berkeley.edu (OMAR RAMADAN) Date: Fri, 15 Jan 2016 11:50:47 -0800 Subject: LCR segfault on SIP invite Message-ID: I'm using LCR as a GSM <-> SIP interface and I've been trying to figure out why MO calls result in a segfault. I am running openbsc on cdc548cb and LCR on c14326641a built and run on an ubuntu 14.04 64bit. >From what I've investigated so far, the request_uri passed to sofia-sip is malformed. Has anyone seen this problem before? Would appreciate pointers. Here are the full logs and stack trace: ** LCR Version 1.14 > 000000 DEBUG (in route.c/getrulesetbyname() line 1928): ruleset main found. > 000000 DEBUG (in sip.cpp/sip_init() line 1997): SIP globals initialized > 000000 DEBUG (in gsm.cpp/mncc_socket_retry_cb() line 1443): Connected to > MNCC socket /tmp/bsc_mncc! > su_port_create(0x6ad410): epoll_create() => 0: OK > su_socket_port_init(0x6ad410, 0x7ffff7dcf880) called > su_pthread_port_init(0x6ad410, 0x7ffff7dcf880) called > nua: nua_create: entering > [New Thread 0x7ffff6c52700 (LWP 11520)] > su_port_create(0x7ffff00008c0): epoll_create() => 0: OK > su_socket_port_init(0x7ffff00008c0, 0x7ffff7dcf880) called > su_pthread_port_init(0x7ffff00008c0, 0x7ffff7dcf880) called > nua: nua_stack_init: entering > nua: nua_stack_set_params: entering > soa_create("default", 0x7ffff0001130, 0x7ffff0001230) called > soa_set_params(static::0x7ffff0001920, ...) called > soa_set_params(static::0x7ffff0001920, ...) called > nta_agent_create: initialized hash tables > nta_agent_create: initialized transports > nta_agent_create: initialized random identifiers > nta_agent_create: initialized timer > nta_agent_create: initialized resolver > tport_create(): 0x7ffff0003df0 > nta: master transport created > tport_bind_server(0x7ffff0003df0) to */127.0.0.1:5062/sip > tport_bind_server(0x7ffff0003df0): calling tport_listen for udp > tport_alloc_primary(0x7ffff0003df0): new primary tport 0x7ffff0004470 > tport_listen(0x7ffff0004470): listening at udp/127.0.0.1:5062/sip > tport_bind_server(0x7ffff0003df0): calling tport_listen for tcp > tport_alloc_primary(0x7ffff0003df0): new primary tport 0x7ffff0004910 > tport_listen(0x7ffff0004910): listening at tcp/127.0.0.1:5062/sip > nta: bound to (127.0.0.1:5062;transport=*) > nta: agent_init_via: SIP/2.0/udp 127.0.0.1:5062 (sip) > nta: agent_init_via: SIP/2.0/tcp 127.0.0.1:5062 (sip) > nta: Via fields initialized > nta: Contact header created > nua_register: Adding contact URL '127.0.0.1' to list. > nua: nua_set_params: entering > nua((nil)): sent signal r_set_params > 000000 DEBUG (in sip.cpp/sip_init_inst() line 1942): SIP interface created > (inst=0x6acce0) > nua((nil)): recv signal r_set_params > nua: nua_stack_set_params: entering > soa_set_params(static::0x7ffff0001920, ...) called > nua((nil)): event r_set_params 200 OK > LCR 1.14 started, waiting for calls... > 000000 TRACE 15.01.16 11:36:21.011 --: LCR 1.14 started, waiting for > calls... > nua: nua_application_event: entering > 000000 DEBUG (in sip.cpp/sip_callback() line 1785): Event 23 from stack > received (handle=(nil)) > 000000 DEBUG (in port.cpp/Port() line 210): new port (1) of type 0x3101, > name 'gsm-0-in' interface 'gsm' > 000000 DEBUG (in gsm.cpp/Pgsm() line 239): Created new GSMPort(gsm-0-in). > 000000 DEBUG (in gsm_bs.cpp/Pgsm_bs() line 56): Created new > GSMBSPort(gsm-0-in). > 000000 TRACE 15.01.16 11:37:28.210 CH(1): New call ref LCR<->BSC callref > new=0x8000000d > 000000 TRACE 15.01.16 11:37:28.210 CH(1): Codec negotiation LCR<->BSC > bearer capa='given by MS' speech version='Full Rate given' > 000000 TRACE 15.01.16 11:37:28.210 CH(1): MNCC_SETUP_IND LCR<->BSC > calling number=639360100037 imsi=901550000000824 dialing number=12345678 > 000000 DEBUG (in endpoint.cpp/Endpoint() line 48): EPOINT(1): Allocating > enpoint 1 and connecting it with: ioport > 000000 DEBUG (in endpoint.cpp/portlist_new() line 150): EPOINT(1) > allocating port_list, attaching to port 1 > 000000 DEBUG (in appbridge.cpp/EndpointAppBridge() line 31): Bridge > endpoint created > 000000 DEBUG (in port.cpp/epointlist_new() line 131): PORT(1) allocating > epoint_list. > 000000 TRACE 15.01.16 11:37:28.211 CH(1): MNCC_CALL_PROC_REQ LCR<->BSC > progress coding=3 location=1 descr=8 > 000000 DEBUG (in port.cpp/new_state() line 283): PORT(gsm-0-in) new state > PORT_STATE_IDLE --> PORT_STATE_IN_PROCEEDING > 000000 TRACE 15.01.16 11:37:28.211 CH(1): MNCC_FRAME_RECV LCR<->BSC > 000000 DEBUG (in gsm_bs.cpp/setup_ind() line 631): Request RTP peer info, > before forwarding setup > 000000 DEBUG (in gsm.cpp/rtp_create_ind() line 869): Got RTP peer info > (7f000001,52103) forwarding setup > 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_SETUP > written from 140733193388033 to 140733193388033 (memory 6b1a50 at file > gsm.cpp, line 872) > 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_SETUP > reading from 1 to 140733193388033 (memory 6b1a50) > 000000 DEBUG (in appbridge.cpp/port_setup() line 94): EPOINT(1) epoint > received setup from='639360100037' to='12345678' > 000000 DEBUG (in port.cpp/Port() line 210): new port (2) of type 0x2002, > name 'sip-0-out' interface 'sip' > 000000 DEBUG (in sip.cpp/Psip() line 72): Created new Psip(sip-0-out). > 000000 DEBUG (in endpoint.cpp/portlist_new() line 150): EPOINT(1) > allocating port_list, attaching to port 2 > 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_SETUP > written from 1 to 2 (memory 6b1a50 at file message.c, line 94) > 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_BRIDGE > written from 1 to 1 (memory 6b6c00 at file appbridge.cpp, line 222) > 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_BRIDGE > written from 1 to 2 (memory 6ba6e0 at file appbridge.cpp, line 225) > 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_SETUP > reading from 140733193388033 to 2 (memory 6b1a50) > 000000 DEBUG (in sip.cpp/message_setup() line 954): Doing Setup (inst > 0x6acce0) > 000000 DEBUG (in sip.cpp/message_setup() line 961): RTP info given by > remote, forward that > 000000 DEBUG (in sip.cpp/message_setup() line 968): local ip 7f000001 port > 52103 > 000000 DEBUG (in sip.cpp/message_setup() line 969): remote ip 00000000 > port 0 > nua: nh_create_handle: entering > 000000 TRACE 15.01.16 11:37:28.816 CH(2): NEW handle handle new=0x6b09c0 > 000000 DEBUG (in sip.cpp/message_setup() line 1038): Using SDP for invite: > v=0 > o=LCR-Sofia-SIP 0 0 IN IP4 127.0.0.1 > s=SIP Call > c=IN IP4 127.0.0.1 > t=0 0 > m=audio 52103 RTP/AVP 3 > a=rtpmap:3 GSM/8000 > 000000 TRACE 15.01.16 11:37:28.816 CH(2): INVITE from uri= > sip:639360100037 at 127.0.0.1:5062 to uri=sip:12345678 at 192.168.40.100:5060 > rtp ip=127.0.0.1 port=52103,52104 payload=GSM:3 > nua: nua_invite: entering > nua(0x6b09c0): sent signal r_invite > 000000 DEBUG (in port.cpp/new_state() line 283): PORT(sip-0-out) new state > PORT_STATE_IDLE --> PORT_STATE_OUT_SETUP > 000000 DEBUG (in sip.cpp/message_setup() line 1069): do proceeding > 000000 DEBUG (in port.cpp/new_state() line 283): PORT(sip-0-out) new state > PORT_STATE_OUT_SETUP --> PORT_STATE_OUT_PROCEEDING > 000000 DEBUG (in message.c/_message_put() line 70): message > MESSAGE_PROCEEDING written from 2 to 1 (memory 6be1c0 at file sip.cpp, line > 1072) > 000000 DEBUG (in port.cpp/epointlist_new() line 131): PORT(2) allocating > epoint_list. > 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_BRIDGE > reading from 1 to 1 (memory 6b6c00) > 000000 DEBUG (in port.cpp/message_epoint() line 657): PORT(gsm-0-in) > bridging to id 1 > nua(0x6b09c0): recv signal r_invite > 000000 DEBUG (in port.cpp/bridge() line 1305): Port 1 creating not > existing bridge 1. > 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_BRIDGE > reading from 1 to 2 (memory 6ba6e0) > 000000 DEBUG (in port.cpp/message_epoint() line 657): PORT(sip-0-out) > bridging to id 1 > nua: nua_stack_set_params: entering > 000000 DEBUG (in port.cpp/bridge() line 1290): Port 2 found existing > bridge 1. > 000000 DEBUG (in message.c/message_get() line 115): message > MESSAGE_PROCEEDING reading from 2 to 1 (memory 6be1c0) > 000000 DEBUG (in appbridge.cpp/port_other() line 259): EPOINT(8) epoint > received message 7070144 from port > 000000 DEBUG (in message.c/_message_put() line 70): message > MESSAGE_PROCEEDING written from 1 to 140733193388033 (memory 6be1c0 at file > message.c, line 94) > 000000 DEBUG (in message.c/message_get() line 115): message > MESSAGE_PROCEEDING reading from 1 to 1 (memory 6be1c0) > nua(0x6b09c0): adding session usage > nta_leg_tcreate(0x7ffff0006b00) > Program received signal SIGSEGV, Segmentation fault. > [Switching to Thread 0x7ffff6c52700 (LWP 11520)] > strlen () at ../sysdeps/x86_64/strlen.S:106 > 106 ../sysdeps/x86_64/strlen.S: No such file or directory. > (gdb) bt > #0 strlen () at ../sysdeps/x86_64/strlen.S:106 > #1 0x00007ffff7b70896 in url_xtra (url=url at entry=0x7ffff00075d0) at > url.c:1048 > #2 0x00007ffff7b2deaf in sip_request_create (home=home at entry=0x7ffff0006fc0, > method=method at entry=sip_method_invite, name=0x7ffff7b916e2 > "INVITE", > name at entry=0x7ffff7b8ed49 "INVITE", uri=uri at entry=0x7ffff00075d0, > version=version at entry=0x0) at sip_basic.c:225 > #3 0x00007ffff7ae3512 in nta_msg_request_complete (msg=msg at entry=0x7ffff0006fc0, > leg=leg at entry=0x7ffff0006b00, method=method at entry=sip_method_invite, > method_name=method_name at entry=0x7ffff7b8ed49 "INVITE", > request_uri=0x7ffff00075d0, request_uri at entry=0x0) at nta.c:3890 > #4 0x00007ffff7b07d92 in nua_client_request_sendmsg (cr=cr at entry=0x7ffff0005af0) > at nua_client.c:803 > #5 0x00007ffff7b08de9 in nua_client_request_try (cr=0x7ffff0005af0) at > nua_client.c:708 > #6 0x00007ffff7b06b93 in nua_client_init_request0 (cr=0x7ffff0005af0) at > nua_client.c:605 > #7 nua_client_init_request (cr=0x7ffff0005af0) at nua_client.c:442 > #8 0x00007ffff7b07246 in nua_client_create (nh=nh at entry=0x6b09c0, > event=event at entry=31, methods=methods at entry=0x7ffff7dc4d20 > , tags=tags at entry=0x6b0eb0) > at nua_client.c:199 > #9 0x00007ffff7b1cc61 in nua_stack_invite (nua=nua at entry=0x6adc80, > nh=nh at entry=0x6b09c0, e=e at entry=nua_r_invite, tags=tags at entry=0x6b0eb0) > at nua_session.c:705 > #10 0x00007ffff7b03eb3 in nua_stack_signal (nua=0x6adc80, msg= out>, ee=0x6b0e88) at nua_stack.c:582 > #11 0x00007ffff7b522b2 in su_base_port_execute_msgs (queue=0x0) at > su_base_port.c:280 > #12 0x00007ffff7b527bd in su_base_port_run (self=0x7ffff00008c0) at > su_base_port.c:335 > #13 0x00007ffff7b52f10 in su_pthread_port_clone_main (varg=0x7fffffffe4c0) > at su_pthread_port.c:324 > #14 0x00007ffff7840182 in start_thread (arg=0x7ffff6c52700) at > pthread_create.c:312 > #15 0x00007ffff6d4d47d in clone () at > ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Fri Jan 15 20:53:19 2016 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 15 Jan 2016 12:53:19 -0800 Subject: LCR segfault on SIP invite In-Reply-To: References: Message-ID: Omar, We're using LCR a lot and I have never seen this AFAIR. Just as a suggestion - make sure you build and run with the same version of the libsofia and there is no binary incompatibility. Please excuse typos. Written with a touchscreen keyboard. -- Regards, Alexander Chemeris CEO Fairwaves, Inc. https://fairwaves.co On Jan 15, 2016 11:50 AM, "OMAR RAMADAN" wrote: > I'm using LCR as a GSM <-> SIP interface and I've been trying to figure > out why MO calls result in a segfault. I am running openbsc on cdc548cb and > LCR on c14326641a built and run on an ubuntu 14.04 64bit. > > From what I've investigated so far, the request_uri passed to sofia-sip is > malformed. > > Has anyone seen this problem before? Would appreciate pointers. > > Here are the full logs and stack trace: > > ** LCR Version 1.14 >> 000000 DEBUG (in route.c/getrulesetbyname() line 1928): ruleset main >> found. >> 000000 DEBUG (in sip.cpp/sip_init() line 1997): SIP globals initialized >> 000000 DEBUG (in gsm.cpp/mncc_socket_retry_cb() line 1443): Connected to >> MNCC socket /tmp/bsc_mncc! >> su_port_create(0x6ad410): epoll_create() => 0: OK >> su_socket_port_init(0x6ad410, 0x7ffff7dcf880) called >> su_pthread_port_init(0x6ad410, 0x7ffff7dcf880) called >> nua: nua_create: entering >> [New Thread 0x7ffff6c52700 (LWP 11520)] >> su_port_create(0x7ffff00008c0): epoll_create() => 0: OK >> su_socket_port_init(0x7ffff00008c0, 0x7ffff7dcf880) called >> su_pthread_port_init(0x7ffff00008c0, 0x7ffff7dcf880) called >> nua: nua_stack_init: entering >> nua: nua_stack_set_params: entering >> soa_create("default", 0x7ffff0001130, 0x7ffff0001230) called >> soa_set_params(static::0x7ffff0001920, ...) called >> soa_set_params(static::0x7ffff0001920, ...) called >> nta_agent_create: initialized hash tables >> nta_agent_create: initialized transports >> nta_agent_create: initialized random identifiers >> nta_agent_create: initialized timer >> nta_agent_create: initialized resolver >> tport_create(): 0x7ffff0003df0 >> nta: master transport created >> tport_bind_server(0x7ffff0003df0) to */127.0.0.1:5062/sip >> tport_bind_server(0x7ffff0003df0): calling tport_listen for udp >> tport_alloc_primary(0x7ffff0003df0): new primary tport 0x7ffff0004470 >> tport_listen(0x7ffff0004470): listening at udp/127.0.0.1:5062/sip >> tport_bind_server(0x7ffff0003df0): calling tport_listen for tcp >> tport_alloc_primary(0x7ffff0003df0): new primary tport 0x7ffff0004910 >> tport_listen(0x7ffff0004910): listening at tcp/127.0.0.1:5062/sip >> nta: bound to (127.0.0.1:5062;transport=*) >> nta: agent_init_via: SIP/2.0/udp 127.0.0.1:5062 (sip) >> nta: agent_init_via: SIP/2.0/tcp 127.0.0.1:5062 (sip) >> nta: Via fields initialized >> nta: Contact header created >> nua_register: Adding contact URL '127.0.0.1' to list. >> nua: nua_set_params: entering >> nua((nil)): sent signal r_set_params >> 000000 DEBUG (in sip.cpp/sip_init_inst() line 1942): SIP interface >> created (inst=0x6acce0) >> nua((nil)): recv signal r_set_params >> nua: nua_stack_set_params: entering >> soa_set_params(static::0x7ffff0001920, ...) called >> nua((nil)): event r_set_params 200 OK >> LCR 1.14 started, waiting for calls... >> 000000 TRACE 15.01.16 11:36:21.011 --: LCR 1.14 started, waiting for >> calls... >> nua: nua_application_event: entering >> 000000 DEBUG (in sip.cpp/sip_callback() line 1785): Event 23 from stack >> received (handle=(nil)) >> 000000 DEBUG (in port.cpp/Port() line 210): new port (1) of type 0x3101, >> name 'gsm-0-in' interface 'gsm' >> 000000 DEBUG (in gsm.cpp/Pgsm() line 239): Created new GSMPort(gsm-0-in). >> 000000 DEBUG (in gsm_bs.cpp/Pgsm_bs() line 56): Created new >> GSMBSPort(gsm-0-in). >> 000000 TRACE 15.01.16 11:37:28.210 CH(1): New call ref LCR<->BSC callref >> new=0x8000000d >> 000000 TRACE 15.01.16 11:37:28.210 CH(1): Codec negotiation LCR<->BSC >> bearer capa='given by MS' speech version='Full Rate given' >> 000000 TRACE 15.01.16 11:37:28.210 CH(1): MNCC_SETUP_IND LCR<->BSC >> calling number=639360100037 imsi=901550000000824 dialing number=12345678 >> 000000 DEBUG (in endpoint.cpp/Endpoint() line 48): EPOINT(1): Allocating >> enpoint 1 and connecting it with: ioport >> 000000 DEBUG (in endpoint.cpp/portlist_new() line 150): EPOINT(1) >> allocating port_list, attaching to port 1 >> 000000 DEBUG (in appbridge.cpp/EndpointAppBridge() line 31): Bridge >> endpoint created >> 000000 DEBUG (in port.cpp/epointlist_new() line 131): PORT(1) allocating >> epoint_list. >> 000000 TRACE 15.01.16 11:37:28.211 CH(1): MNCC_CALL_PROC_REQ LCR<->BSC >> progress coding=3 location=1 descr=8 >> 000000 DEBUG (in port.cpp/new_state() line 283): PORT(gsm-0-in) new state >> PORT_STATE_IDLE --> PORT_STATE_IN_PROCEEDING >> 000000 TRACE 15.01.16 11:37:28.211 CH(1): MNCC_FRAME_RECV LCR<->BSC >> 000000 DEBUG (in gsm_bs.cpp/setup_ind() line 631): Request RTP peer info, >> before forwarding setup >> 000000 DEBUG (in gsm.cpp/rtp_create_ind() line 869): Got RTP peer info >> (7f000001,52103) forwarding setup >> 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_SETUP >> written from 140733193388033 to 140733193388033 (memory 6b1a50 at file >> gsm.cpp, line 872) >> 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_SETUP >> reading from 1 to 140733193388033 (memory 6b1a50) >> 000000 DEBUG (in appbridge.cpp/port_setup() line 94): EPOINT(1) epoint >> received setup from='639360100037' to='12345678' >> 000000 DEBUG (in port.cpp/Port() line 210): new port (2) of type 0x2002, >> name 'sip-0-out' interface 'sip' >> 000000 DEBUG (in sip.cpp/Psip() line 72): Created new Psip(sip-0-out). >> 000000 DEBUG (in endpoint.cpp/portlist_new() line 150): EPOINT(1) >> allocating port_list, attaching to port 2 >> 000000 DEBUG (in message.c/_message_put() line 70): message MESSAGE_SETUP >> written from 1 to 2 (memory 6b1a50 at file message.c, line 94) >> 000000 DEBUG (in message.c/_message_put() line 70): message >> MESSAGE_BRIDGE written from 1 to 1 (memory 6b6c00 at file appbridge.cpp, >> line 222) >> 000000 DEBUG (in message.c/_message_put() line 70): message >> MESSAGE_BRIDGE written from 1 to 2 (memory 6ba6e0 at file appbridge.cpp, >> line 225) >> 000000 DEBUG (in message.c/message_get() line 115): message MESSAGE_SETUP >> reading from 140733193388033 to 2 (memory 6b1a50) >> 000000 DEBUG (in sip.cpp/message_setup() line 954): Doing Setup (inst >> 0x6acce0) >> 000000 DEBUG (in sip.cpp/message_setup() line 961): RTP info given by >> remote, forward that >> 000000 DEBUG (in sip.cpp/message_setup() line 968): local ip 7f000001 >> port 52103 >> 000000 DEBUG (in sip.cpp/message_setup() line 969): remote ip 00000000 >> port 0 >> nua: nh_create_handle: entering >> 000000 TRACE 15.01.16 11:37:28.816 CH(2): NEW handle handle new=0x6b09c0 >> 000000 DEBUG (in sip.cpp/message_setup() line 1038): Using SDP for >> invite: v=0 >> o=LCR-Sofia-SIP 0 0 IN IP4 127.0.0.1 >> s=SIP Call >> c=IN IP4 127.0.0.1 >> t=0 0 >> m=audio 52103 RTP/AVP 3 >> a=rtpmap:3 GSM/8000 >> 000000 TRACE 15.01.16 11:37:28.816 CH(2): INVITE from uri= >> sip:639360100037 at 127.0.0.1:5062 to uri=sip:12345678 at 192.168.40.100:5060 >> rtp ip=127.0.0.1 port=52103,52104 payload=GSM:3 >> nua: nua_invite: entering >> nua(0x6b09c0): sent signal r_invite >> 000000 DEBUG (in port.cpp/new_state() line 283): PORT(sip-0-out) new >> state PORT_STATE_IDLE --> PORT_STATE_OUT_SETUP >> 000000 DEBUG (in sip.cpp/message_setup() line 1069): do proceeding >> 000000 DEBUG (in port.cpp/new_state() line 283): PORT(sip-0-out) new >> state PORT_STATE_OUT_SETUP --> PORT_STATE_OUT_PROCEEDING >> 000000 DEBUG (in message.c/_message_put() line 70): message >> MESSAGE_PROCEEDING written from 2 to 1 (memory 6be1c0 at file sip.cpp, line >> 1072) >> 000000 DEBUG (in port.cpp/epointlist_new() line 131): PORT(2) allocating >> epoint_list. >> 000000 DEBUG (in message.c/message_get() line 115): message >> MESSAGE_BRIDGE reading from 1 to 1 (memory 6b6c00) >> 000000 DEBUG (in port.cpp/message_epoint() line 657): PORT(gsm-0-in) >> bridging to id 1 >> nua(0x6b09c0): recv signal r_invite >> 000000 DEBUG (in port.cpp/bridge() line 1305): Port 1 creating not >> existing bridge 1. >> 000000 DEBUG (in message.c/message_get() line 115): message >> MESSAGE_BRIDGE reading from 1 to 2 (memory 6ba6e0) >> 000000 DEBUG (in port.cpp/message_epoint() line 657): PORT(sip-0-out) >> bridging to id 1 >> nua: nua_stack_set_params: entering >> 000000 DEBUG (in port.cpp/bridge() line 1290): Port 2 found existing >> bridge 1. >> 000000 DEBUG (in message.c/message_get() line 115): message >> MESSAGE_PROCEEDING reading from 2 to 1 (memory 6be1c0) >> 000000 DEBUG (in appbridge.cpp/port_other() line 259): EPOINT(8) epoint >> received message 7070144 from port >> 000000 DEBUG (in message.c/_message_put() line 70): message >> MESSAGE_PROCEEDING written from 1 to 140733193388033 (memory 6be1c0 at file >> message.c, line 94) >> 000000 DEBUG (in message.c/message_get() line 115): message >> MESSAGE_PROCEEDING reading from 1 to 1 (memory 6be1c0) >> nua(0x6b09c0): adding session usage >> nta_leg_tcreate(0x7ffff0006b00) >> Program received signal SIGSEGV, Segmentation fault. >> [Switching to Thread 0x7ffff6c52700 (LWP 11520)] >> strlen () at ../sysdeps/x86_64/strlen.S:106 >> 106 ../sysdeps/x86_64/strlen.S: No such file or directory. >> (gdb) bt >> #0 strlen () at ../sysdeps/x86_64/strlen.S:106 >> #1 0x00007ffff7b70896 in url_xtra (url=url at entry=0x7ffff00075d0) at >> url.c:1048 >> #2 0x00007ffff7b2deaf in sip_request_create (home=home at entry=0x7ffff0006fc0, >> method=method at entry=sip_method_invite, name=0x7ffff7b916e2 >> "INVITE", >> name at entry=0x7ffff7b8ed49 "INVITE", uri=uri at entry=0x7ffff00075d0, >> version=version at entry=0x0) at sip_basic.c:225 >> #3 0x00007ffff7ae3512 in nta_msg_request_complete (msg=msg at entry=0x7ffff0006fc0, >> leg=leg at entry=0x7ffff0006b00, method=method at entry=sip_method_invite, >> method_name=method_name at entry=0x7ffff7b8ed49 "INVITE", >> request_uri=0x7ffff00075d0, request_uri at entry=0x0) at nta.c:3890 >> #4 0x00007ffff7b07d92 in nua_client_request_sendmsg (cr=cr at entry=0x7ffff0005af0) >> at nua_client.c:803 >> #5 0x00007ffff7b08de9 in nua_client_request_try (cr=0x7ffff0005af0) at >> nua_client.c:708 >> #6 0x00007ffff7b06b93 in nua_client_init_request0 (cr=0x7ffff0005af0) at >> nua_client.c:605 >> #7 nua_client_init_request (cr=0x7ffff0005af0) at nua_client.c:442 >> #8 0x00007ffff7b07246 in nua_client_create (nh=nh at entry=0x6b09c0, >> event=event at entry=31, methods=methods at entry=0x7ffff7dc4d20 >> , tags=tags at entry=0x6b0eb0) >> at nua_client.c:199 >> #9 0x00007ffff7b1cc61 in nua_stack_invite (nua=nua at entry=0x6adc80, >> nh=nh at entry=0x6b09c0, e=e at entry=nua_r_invite, tags=tags at entry=0x6b0eb0) >> at nua_session.c:705 >> #10 0x00007ffff7b03eb3 in nua_stack_signal (nua=0x6adc80, msg=> out>, ee=0x6b0e88) at nua_stack.c:582 >> #11 0x00007ffff7b522b2 in su_base_port_execute_msgs (queue=0x0) at >> su_base_port.c:280 >> #12 0x00007ffff7b527bd in su_base_port_run (self=0x7ffff00008c0) at >> su_base_port.c:335 >> #13 0x00007ffff7b52f10 in su_pthread_port_clone_main >> (varg=0x7fffffffe4c0) at su_pthread_port.c:324 >> #14 0x00007ffff7840182 in start_thread (arg=0x7ffff6c52700) at >> pthread_create.c:312 >> #15 0x00007ffff6d4d47d in clone () at >> ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From nhofmeyr at sysmocom.de Mon Jan 18 10:09:35 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 18 Jan 2016 11:09:35 +0100 Subject: OAP depends on libgtp? (openbsc:6cacc56d) Message-ID: <20160118100935.GA1392@dub6> Hi Alexander, about your commit on openbsc, merged as 6cacc56d: libgtp should not be a prerequisite for OAP. OAP is a rather simple protocol built on an IPA connection and doesn't really relate to GTP at all. So if your build of OAP was dependent on libgtp, that's a bug, and probably my fault. Could you please verify / indicate the failure you saw so we/I can fix it? Thanks! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From nhofmeyr at sysmocom.de Mon Jan 18 10:12:12 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 18 Jan 2016 11:12:12 +0100 Subject: OAP depends on libgtp? (openbsc:6cacc56d) In-Reply-To: <20160118100935.GA1392@dub6> References: <20160118100935.GA1392@dub6> Message-ID: <20160118101212.GB1392@dub6> On Mon, Jan 18, 2016 at 11:09:35AM +0100, Neels Hofmeyr wrote: > about your commit on openbsc, merged as 6cacc56d: libgtp should not be a > prerequisite for OAP. OAP is a rather simple protocol built on an IPA > connection and doesn't really relate to GTP at all. Oh, and same difference for c-ares. ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From nhofmeyr at sysmocom.de Mon Jan 18 11:47:47 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 18 Jan 2016 12:47:47 +0100 Subject: dbi deprecation Message-ID: <20160118114747.GC1392@dub6> Hi, I'm just noticing warning: ?dbi_initialize? is deprecated (declared at /usr/include/dbi/dbi.h:169) called from openbsc/openbsc/src/libmsc/db.c:db_init() (and a couple more dbi deprecations) Should we do something about it? ...rather: who and when? ;) ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Mon Jan 18 12:20:18 2016 From: holger at freyther.de (Holger Freyther) Date: Mon, 18 Jan 2016 13:20:18 +0100 Subject: dbi deprecation In-Reply-To: <20160118114747.GC1392@dub6> References: <20160118114747.GC1392@dub6> Message-ID: > On 18 Jan 2016, at 12:47, Neels Hofmeyr wrote: > > > Should we do something about it? > ...rather: who and when? ;) replace libdbi with direct calls to sqlite3. The "new" libdbi has severy memory corruption issues and seems to be unmaintained. From suraev at alumni.ntnu.no Mon Jan 18 14:02:58 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Mon, 18 Jan 2016 15:02:58 +0100 Subject: dbi deprecation In-Reply-To: References: <20160118114747.GC1392@dub6> Message-ID: <569CF092.4050506@alumni.ntnu.no> Another option would be to migrate to http://www.tildeslash.com/libzdb/ It's GPL, thread-safe and allows trivial migration between database engines in case we would like to use something more advanced than sqlite in future (if I'm not mistake this been discussed several times in ML before). cheers, Max. From holger at freyther.de Mon Jan 18 15:56:59 2016 From: holger at freyther.de (Holger Freyther) Date: Mon, 18 Jan 2016 16:56:59 +0100 Subject: Smalltalk scalable SMSC project Message-ID: <9047F009-0798-4ED9-8211-BA5D515B9295@freyther.de> Hi all, new year, new approaches. In December I was tasked to think about a real SMSC with SMPP input and SS7 output (or SMPP in the future) and I wrote down my ideas[1] about data storage, approach, how to achieve scaling. What is missing fail-over but there are some ideas for this as well. The implementation will be done using Pharo and at least the first data storage will use mongodb >= 3.2. In the past my Pharo work has not been hosted in git but for this project it will change and maybe it creates some more visibility, historically documentation and debian packages were not too visible but that will be different this time as well. If you are interested in specification, Smalltalk, testing, load testing, SS7 or such please join me in the development. happy hacking holger [1] https://github.com/zecke/osmo-smsc/blob/master/README.asciidoc it will move to git.osmocom.org but I just wanted to have online asciidoc rendering. From laforge at gnumonks.org Mon Jan 18 15:29:36 2016 From: laforge at gnumonks.org (Harald Welte) Date: Mon, 18 Jan 2016 16:29:36 +0100 Subject: LCR segfault on SIP invite In-Reply-To: References: Message-ID: <20160118152936.GL17432@nataraja> Hi Omar, On Fri, Jan 15, 2016 at 11:50:47AM -0800, OMAR RAMADAN wrote: > I'm using LCR as a GSM <-> SIP interface and I've been trying to figure out > why MO calls result in a segfault. I am running openbsc on cdc548cb and LCR > on c14326641a built and run on an ubuntu 14.04 64bit. As this sounds like an LCR issue, and not an OpenBSC one,please consider posting this to the isdn4linux mailing list, as indicated at the bottom of the page http://www.linux-call-router.de/ -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From holger at freyther.de Mon Jan 18 15:56:59 2016 From: holger at freyther.de (Holger Freyther) Date: Mon, 18 Jan 2016 16:56:59 +0100 Subject: Smalltalk scalable SMSC project Message-ID: <9047F009-0798-4ED9-8211-BA5D515B9295@freyther.de> Hi all, new year, new approaches. In December I was tasked to think about a real SMSC with SMPP input and SS7 output (or SMPP in the future) and I wrote down my ideas[1] about data storage, approach, how to achieve scaling. What is missing fail-over but there are some ideas for this as well. The implementation will be done using Pharo and at least the first data storage will use mongodb >= 3.2. In the past my Pharo work has not been hosted in git but for this project it will change and maybe it creates some more visibility, historically documentation and debian packages were not too visible but that will be different this time as well. If you are interested in specification, Smalltalk, testing, load testing, SS7 or such please join me in the development. happy hacking holger [1] https://github.com/zecke/osmo-smsc/blob/master/README.asciidoc it will move to git.osmocom.org but I just wanted to have online asciidoc rendering. From laforge at gnumonks.org Mon Jan 18 19:13:00 2016 From: laforge at gnumonks.org (Harald Welte) Date: Mon, 18 Jan 2016 20:13:00 +0100 Subject: trx-bench results for AMD G-T40E Message-ID: <20160118191300.GO17432@nataraja> Hi Thomas, in case you'd like to add it to your benchmark results, below is a run of trx-bench on a Debian stable (jessie) system on a G-T40E CPU @ 800MHz. What I find surprising is that it appears to be comparable than the Atom D2500 @ 1.86GHz, despite the Atom running at twice the clock rate... More details see attachments. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) -------------- next part -------------- processor : 0 vendor_id : AuthenticAMD cpu family : 20 model : 2 model name : AMD G-T40E Processor stepping : 0 microcode : 0x5000101 cpu MHz : 800.000 cache size : 512 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 6 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt arat hw_pstate npt lbrv svm_lock nrip_save pausefilter vmmcall bogomips : 2000.01 TLB size : 1024 4K pages clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: ts ttp tm stc 100mhzsteps hwpstate processor : 1 vendor_id : AuthenticAMD cpu family : 20 model : 2 model name : AMD G-T40E Processor stepping : 0 microcode : 0x5000101 cpu MHz : 800.000 cache size : 512 KB physical id : 0 siblings : 2 core id : 1 cpu cores : 2 apicid : 1 initial apicid : 1 fpu : yes fpu_exception : yes cpuid level : 6 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt arat hw_pstate npt lbrv svm_lock nrip_save pausefilter vmmcall bogomips : 2000.01 TLB size : 1024 4K pages clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: ts ttp tm stc 100mhzsteps hwpstate -------------- next part -------------- [+] Testing: GSM xCCH (non-recursive, flushed, not punctured) [.] Input length : ret = 224 exp = 224 -> OK [.] Output length : ret = 456 exp = 456 -> OK [.] Pre computed vector checks: [..] Encoding: OK [..] Decoding base: [..] Decoding SIMD: [..] Code N 2 [..] Code K 5 [..] Decoding: OK [.] BER tests: [..] Testing base: [..] Input BER.......................... 0.023499 [..] Output FER......................... 0.004800 [..] Testing SIMD: [..] Input BER.......................... 0.023390 [..] Output FER......................... 0.000000 [.] Performance benchmark: [..] Testing base: [..] Encoding / Decoding 10000 bursts on 1 thread(s): [..] Elapsed time....................... 3.427718 secs [..] Rate............................... 1.330331 Mbps [..] Testing SIMD: [..] Encoding / Decoding 10000 bursts on 1 thread(s): [..] Elapsed time....................... 0.425603 secs [..] Rate............................... 10.714210 Mbps [..] Speedup............................ 8.053792 [+] Testing: GSM TCH/AFS 7.95 (recursive, flushed, punctured) [.] Input length : ret = 165 exp = 165 -> OK [.] Output length : ret = 448 exp = 448 -> OK [.] Pre computed vector checks: [..] Encoding: OK [..] Decoding base: [..] Decoding SIMD: [..] Code N 3 [..] Code K 7 [..] Decoding: OK [.] BER tests: [..] Testing base: [..] Input BER.......................... 0.023450 [..] Output FER......................... 0.000300 [..] Testing SIMD: [..] Input BER.......................... 0.023444 [..] Output FER......................... 0.000000 [.] Performance benchmark: [..] Testing base: [..] Encoding / Decoding 10000 bursts on 1 thread(s): [..] Elapsed time....................... 11.293366 secs [..] Rate............................... 0.396693 Mbps [..] Testing SIMD: [..] Encoding / Decoding 10000 bursts on 1 thread(s): [..] Elapsed time....................... 0.686461 secs [..] Rate............................... 6.526227 Mbps [..] Speedup............................ 16.451577 -------------- next part -------------- --- Floating point to integer conversions -- Testing 40000 iterations of 12480 values - Measuring conversion time - Elapsed time base... 2.548129 secs - Validating SSE conversion results... PASS - Measuring conversion time - Elapsed time SSE ... 0.960012 secs - Quotient... 2.654268 -- Testing 40000 iterations of 3120 values - Measuring conversion time - Elapsed time base... 0.640163 secs - Validating SSE conversion results... PASS - Measuring conversion time - Elapsed time SSE ... 0.191270 secs - Quotient... 3.346908 --- Skipping integer-float conversions (SSE4 only) -------------- next part -------------- Convolving 156 * 4 samples for 10000 iterations ----------------- Filter length 4 Base real-complex elapsed time... 0.372130 secs SSE real-complex elapsed time... 0.241270 secs Quotient 1.542380 Base complex-complex elapsed time... 0.521219 secs SSE complex-complex elapsed time... 0.382408 secs Quotient 1.362992 Filter length 8 Base real-complex elapsed time... 0.573190 secs SSE real-complex elapsed time... 0.326938 secs Quotient 1.753207 Base complex-complex elapsed time... 0.873947 secs SSE complex-complex elapsed time... 0.602019 secs Quotient 1.451693 Filter length 12 Base real-complex elapsed time... 0.776067 secs SSE real-complex elapsed time... 0.396321 secs Quotient 1.958178 Base complex-complex elapsed time... 1.226749 secs SSE complex-complex elapsed time... 0.752869 secs Quotient 1.629432 Filter length 16 Base real-complex elapsed time... 0.977423 secs SSE real-complex elapsed time... 0.497255 secs Quotient 1.965637 Base complex-complex elapsed time... 1.579161 secs SSE complex-complex elapsed time... 0.922173 secs Quotient 1.712435 Filter length 20 Base real-complex elapsed time... 1.179777 secs SSE real-complex elapsed time... 0.585324 secs Quotient 2.015596 Base complex-complex elapsed time... 1.931793 secs SSE complex-complex elapsed time... 1.104140 secs Quotient 1.749591 Filter length 24 Base complex-complex elapsed time... 2.284363 secs SSE complex-complex elapsed time... 1.242570 secs Quotient 1.838418 Filter length 32 Base complex-complex elapsed time... 3.125769 secs SSE complex-complex elapsed time... 1.562846 secs Quotient 2.000049 Filter length 64 Base complex-complex elapsed time... 5.945989 secs SSE complex-complex elapsed time... 2.844491 secs Quotient 2.090353 Filter length 128 Base complex-complex elapsed time... 11.598979 secs SSE complex-complex elapsed time... 5.407983 secs Quotient 2.144788 From nhofmeyr at sysmocom.de Tue Jan 19 10:04:41 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Tue, 19 Jan 2016 11:04:41 +0100 Subject: dbi deprecation In-Reply-To: <569CF092.4050506@alumni.ntnu.no> References: <20160118114747.GC1392@dub6> <569CF092.4050506@alumni.ntnu.no> Message-ID: <20160119100441.GA1824@dub6> On Mon, Jan 18, 2016 at 03:02:58PM +0100, Max (?) wrote: > Another option would be to migrate to http://www.tildeslash.com/libzdb/ > > It's GPL, thread-safe and allows trivial migration between database engines in case > we would like to use something more advanced than sqlite in future (if I'm not > mistake this been discussed several times in ML before). So I take it the priority for this is relatively low? Should I spend time on this now, or rather let it gather dust for a bit longer? My mind _is_ quite occupied by Iu-CS, and according to Douglas Adams, as soon as one tries to add an 8th thought, another would drop out of your head unnoticed... ~Neels > > cheers, > Max. > -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Wed Jan 20 19:15:44 2016 From: holger at freyther.de (Holger Freyther) Date: Wed, 20 Jan 2016 20:15:44 +0100 Subject: [PATCH] Enable address sanitizer for tests. In-Reply-To: <1453305464-21916-1-git-send-email-suraev@alumni.ntnu.no> References: <1453305464-21916-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 20 Jan 2016, at 16:57, suraev at alumni.ntnu.no wrote: > > From: Max Hi, > Some tests are leaky which is ok since it's one-shot programs > anyway. For them mem. leak sanitizer is explicitly disabled via > env. variables. I think it is best to use the OpenBSC mailinglist for libosmocore and other libraries. From my point of view it really makes sense to have ASAN build and run the tests (and include leak check if we can ignore some globals) but I have a couple of issues with the specific patch: 1.) not all compilers we use support ASAN 2.) Just compiling the test doesn't help us to verify the library itself. It needs to be instrumented too! So my proposal would be: 1.) We get a gcc 5.x or clang on one of the linux builders (or I will create one) 2.) We use your AT_CHECK check so we can pass this variable from the outside too. 3.) We have a Jenkins nightly job that does make CFLAGS+="-fsanitize.." CXXFLAGS+=.. check on all dependencies > +AT_COLOR_TESTS What does this give us? > -AT_CHECK([$abs_top_builddir/tests/msgfile/msgfile_test], [0], [expout]) > +AT_CHECK([ASAN_OPTIONS="detect_leaks=0" $abs_top_builddir/tests/msgfile/msgfile_test], [0], [expout]) Did you have a look at osmo-bts and how I sneaked in support for using qemu to execute the tests? From suraev at alumni.ntnu.no Thu Jan 21 15:15:08 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 21 Jan 2016 16:15:08 +0100 Subject: [PATCH] Add workaround to prevent out-of-bounds error. Message-ID: <1453389308-4532-1-git-send-email-suraev@alumni.ntnu.no> From: Max Refactor and simplify gsm 7 bit decoder. Remove useless tests for legacy functions. Make tests more human-readable. Replace assert inside the library with returning error code. Ticket: OW#1198 Sponsored-by: On-Waves ehf --- src/gsm/gsm_utils.c | 35 +++++++++++++++++------------- tests/sms/sms_test.c | 59 ++++++++++++++++++++++++--------------------------- tests/sms/sms_test.ok | 28 +++++++++--------------- 3 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index fad59bc..bcc0271 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -126,18 +126,17 @@ uint8_t gsm_get_octet_len(const uint8_t sept_len){ return octet_len; } -/* GSM 03.38 6.2.1 Character unpacking */ +/* GSM 03.38 6.2.1 Character unpacking + * returns -1 on size errors, number of characters otherwise + */ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind) { - int i = 0; - int shift = 0; - uint8_t c7, c8; - uint8_t next_is_ext = 0; + unsigned shift = 0; + uint8_t c7, c8, next_is_ext = 0, lu, ru, maxlen = gsm_get_octet_len(septet_l); const char *text_buf_begin = text; const char *text_buf_end = text + n; - int nchars; - OSMO_ASSERT (n > 0); + if (n < 1) return -1; /* skip the user data header */ if (ud_hdr_ind) { @@ -148,12 +147,20 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_ septet_l = septet_l - shift; } + unsigned i, l, r; for (i = 0; i < septet_l && text != text_buf_end - 1; i++) { - c7 = - ((user_data[((i + shift) * 7 + 7) >> 3] << - (7 - (((i + shift) * 7 + 7) & 7))) | - (user_data[((i + shift) * 7) >> 3] >> - (((i + shift) * 7) & 7))) & 0x7f; + + l = ((i + shift) * 7 + 7) >> 3; + r = ((i + shift) * 7) >> 3; + + if (l >= maxlen) + lu = 0; // workaround to prevent getting out of bounds + else + lu = user_data[l] << (7 - (((i + shift) * 7 + 7) & 7)); + + ru = user_data[r] >> (((i + shift) * 7) & 7); + + c7 = (lu | ru) & 0x7f; if (next_is_ext) { /* this is an extension character */ @@ -169,11 +176,9 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_ *(text++) = c8; } - nchars = text - text_buf_begin; - *text = '\0'; - return nchars; + return text - text_buf_begin; } int gsm_7bit_decode_n(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l) diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c index cdd4158..1927925 100644 --- a/tests/sms/sms_test.c +++ b/tests/sms/sms_test.c @@ -44,6 +44,7 @@ struct test_case { const uint16_t expected_octet_length; const uint16_t expected_septet_length; const uint8_t ud_hdr_ind; + const char * descr; }; static const char simple_text[] = "test text"; @@ -131,6 +132,7 @@ static const struct test_case test_multiple_encode[] = .expected_octet_length = sizeof(concatenated_part1_enc), .expected_septet_length = concatenated_part1_septet_length, .ud_hdr_ind = 1, + .descr = "concatenated text p1" }, { .input = (const uint8_t *) concatenated_text, @@ -138,6 +140,7 @@ static const struct test_case test_multiple_encode[] = .expected_octet_length = sizeof(concatenated_part2_enc), .expected_septet_length = concatenated_part2_septet_length, .ud_hdr_ind = 1, + .descr = "concatenated text p2" }, }; @@ -149,6 +152,7 @@ static const struct test_case test_encode[] = .expected_octet_length = sizeof(simple_enc), .expected_septet_length = simple_septet_length, .ud_hdr_ind = 0, + .descr = "simple text" }, { .input = (const uint8_t *) escape_text, @@ -156,6 +160,7 @@ static const struct test_case test_encode[] = .expected_octet_length = sizeof(escape_enc), .expected_septet_length = escape_septet_length, .ud_hdr_ind = 0, + .descr = "escape text" }, { .input = (const uint8_t *) enhanced_text, @@ -163,6 +168,7 @@ static const struct test_case test_encode[] = .expected_octet_length = sizeof(enhanced_enc), .expected_septet_length = enhanced_septet_length, .ud_hdr_ind = 0, + .descr = "enhanced text" }, { .input = (const uint8_t *) enhancedV2_text, @@ -170,6 +176,7 @@ static const struct test_case test_encode[] = .expected_octet_length = sizeof(enhancedV2_enc), .expected_septet_length = enhancedV2_septet_length, .ud_hdr_ind = 0, + .descr = "enhanced text v2" }, }; @@ -181,6 +188,7 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) simple_text, .expected_septet_length = simple_septet_length, .ud_hdr_ind = 0, + .descr = "simple text" }, { .input = escape_enc, @@ -188,6 +196,7 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) escape_text, .expected_septet_length = escape_septet_length, .ud_hdr_ind = 0, + .descr = "escape text" }, { .input = enhanced_enc, @@ -195,6 +204,7 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) enhanced_text, .expected_septet_length = enhanced_septet_length, .ud_hdr_ind = 0, + .descr = "enhanced text" }, { .input = enhancedV2_enc, @@ -202,6 +212,7 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) enhancedV2_text, .expected_septet_length = enhancedV2_septet_length, .ud_hdr_ind = 0, + .descr = "enhanced text v2" }, { .input = concatenated_part1_enc, @@ -209,6 +220,7 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) splitted_text_part1, .expected_septet_length = concatenated_part1_septet_length_with_header, .ud_hdr_ind = 1, + .descr = "concatenated text p1" }, { .input = concatenated_part2_enc, @@ -216,7 +228,8 @@ static const struct test_case test_decode[] = .expected = (const uint8_t *) splitted_text_part2, .expected_septet_length = concatenated_part2_septet_length_with_header, .ud_hdr_ind = 1, - }, + .descr = "concatenated text p2" + }, }; static void test_octet_return() @@ -288,29 +301,17 @@ int main(int argc, char** argv) /* test 7-bit encoding */ for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { - /* Test legacy function (return value only) */ - septet_length = gsm_7bit_encode(coded, - (const char *) test_encode[i].input); - printf("Legacy encode case %d: " - "septet length %d (expected %d)\n" - , i - , septet_length, test_encode[i].expected_septet_length - ); - OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); - - /* Test new function */ memset(coded, 0x42, sizeof(coded)); septet_length = gsm_7bit_encode_n(coded, sizeof(coded), (const char *) test_encode[i].input, &octets_written); computed_octet_length = gsm_get_octet_len(septet_length); - printf("Encode case %d: " - "Octet length %d (expected %d, computed %d), " - "septet length %d (expected %d)\n" - , i - , octets_written, test_encode[i].expected_octet_length, computed_octet_length - , septet_length, test_encode[i].expected_septet_length - ); + printf("Encode case %d (%s): " + "Octet length %d (expected %d, computed %d, test %s), " + "septet length %d (expected %d, test %s)\n", + i, test_encode[i].descr, + octets_written, test_encode[i].expected_octet_length, computed_octet_length, (test_encode[i].expected_octet_length == computed_octet_length) ? "OK" : "FAIL", + septet_length, test_encode[i].expected_septet_length, (septet_length == test_encode[i].expected_septet_length) ? "OK" : "FAIL"); OSMO_ASSERT (octets_written == test_encode[i].expected_octet_length); OSMO_ASSERT (octets_written == computed_octet_length); @@ -377,22 +378,18 @@ int main(int argc, char** argv) /* test 7-bit decoding */ for (i = 0; i < ARRAY_SIZE(test_decode); ++i) { - /* Test legacy function (return value only) */ - if (!test_decode[i].ud_hdr_ind) { - nchars = gsm_7bit_decode(result, test_decode[i].input, - test_decode[i].expected_septet_length); - printf("Legacy decode case %d: " - "return value %d (expected %d)\n", - i, nchars, test_decode[i].expected_septet_length); - } - - /* Test new function */ memset(result, 0x42, sizeof(result)); +// printf("Attempting to 7 bit decode %d to %d with exp %d and ind %d\n", test_decode[i].input_length, sizeof(result), test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); nchars = gsm_7bit_decode_n_hdr(result, sizeof(result), test_decode[i].input, test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); - printf("Decode case %d: return value %d (expected %d)\n", i, nchars, strlen(result)); + printf("Decode case %d (%s): return value %d, expected %d, test %s\n", i, test_decode[i].descr, nchars, strlen(result), (strlen(result) == nchars) ? "OK" : "FAIL"); + + int res = strcmp(result, (const char *) test_decode[i].expected); + if(0 != res) { + printf("%d:\n%s\n%s\n", res, osmo_hexdump(result, strlen(result)), + osmo_hexdump(test_decode[i].expected, strlen(result))); + } - OSMO_ASSERT(strcmp(result, (const char *) test_decode[i].expected) == 0); OSMO_ASSERT(nchars == strlen(result)); /* check buffer limiting */ diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok index fa536ea..144e602 100644 --- a/tests/sms/sms_test.ok +++ b/tests/sms/sms_test.ok @@ -1,22 +1,14 @@ SMS testing -Legacy encode case 0: septet length 9 (expected 9) -Encode case 0: Octet length 8 (expected 8, computed 8), septet length 9 (expected 9) -Legacy encode case 1: septet length 41 (expected 41) -Encode case 1: Octet length 36 (expected 36, computed 36), septet length 41 (expected 41) -Legacy encode case 2: septet length 39 (expected 39) -Encode case 2: Octet length 35 (expected 35, computed 35), septet length 39 (expected 39) -Legacy encode case 3: septet length 40 (expected 40) -Encode case 3: Octet length 35 (expected 35, computed 35), septet length 40 (expected 40) -Legacy decode case 0: return value 9 (expected 9) -Decode case 0: return value 9 (expected 9) -Legacy decode case 1: return value 41 (expected 41) -Decode case 1: return value 40 (expected 40) -Legacy decode case 2: return value 39 (expected 39) -Decode case 2: return value 31 (expected 31) -Legacy decode case 3: return value 40 (expected 40) -Decode case 3: return value 32 (expected 32) -Decode case 4: return value 153 (expected 153) -Decode case 5: return value 40 (expected 40) +Encode case 0 (simple text): Octet length 8 (expected 8, computed 8, test OK), septet length 9 (expected 9, test OK) +Encode case 1 (escape text): Octet length 36 (expected 36, computed 36, test OK), septet length 41 (expected 41, test OK) +Encode case 2 (enhanced text): Octet length 35 (expected 35, computed 35, test OK), septet length 39 (expected 39, test OK) +Encode case 3 (enhanced text v2): Octet length 35 (expected 35, computed 35, test OK), septet length 40 (expected 40, test OK) +Decode case 0 (simple text): return value 9, expected 9, test OK +Decode case 1 (escape text): return value 40, expected 40, test OK +Decode case 2 (enhanced text): return value 31, expected 31, test OK +Decode case 3 (enhanced text v2): return value 32, expected 32, test OK +Decode case 4 (concatenated text p1): return value 153, expected 153, test OK +Decode case 5 (concatenated text p2): return value 40, expected 40, test OK Encoding some tests and printing number of septets/octets SEPTETS: 8 OCTETS: 7 Done -- 2.5.0 From suraev at alumni.ntnu.no Thu Jan 21 15:52:40 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 21 Jan 2016 16:52:40 +0100 Subject: [PATCH] Fix sporadic out-of-bounds error Message-ID: <1453391560-17219-1-git-send-email-suraev@alumni.ntnu.no> From: Max This code dealing with bit shifting sometimes gets 1 byte beyond array boundary while calculating index. This is now explicitly checked and prevented. Ticket: OW#1198 Sponsored-by: On-Waves ehf --- src/gsm/gsm_utils.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index fad59bc..e8e452f 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -129,13 +129,11 @@ uint8_t gsm_get_octet_len(const uint8_t sept_len){ /* GSM 03.38 6.2.1 Character unpacking */ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind) { - int i = 0; - int shift = 0; - uint8_t c7, c8; - uint8_t next_is_ext = 0; + unsigned shift = 0; + uint8_t c7, c8, next_is_ext = 0, lu, ru; + const uint8_t maxlen = gsm_get_octet_len(septet_l); const char *text_buf_begin = text; const char *text_buf_end = text + n; - int nchars; OSMO_ASSERT (n > 0); @@ -148,12 +146,24 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_ septet_l = septet_l - shift; } + unsigned i, l, r; for (i = 0; i < septet_l && text != text_buf_end - 1; i++) { - c7 = - ((user_data[((i + shift) * 7 + 7) >> 3] << - (7 - (((i + shift) * 7 + 7) & 7))) | - (user_data[((i + shift) * 7) >> 3] >> - (((i + shift) * 7) & 7))) & 0x7f; + + l = ((i + shift) * 7 + 7) >> 3; + r = ((i + shift) * 7) >> 3; + + /* the left side index is always >= right side index + sometimes it even gets beyond array boundary + check for that explicitly and force 0 instead + */ + if (l >= maxlen) + lu = 0; + else + lu = user_data[l] << (7 - (((i + shift) * 7 + 7) & 7)); + + ru = user_data[r] >> (((i + shift) * 7) & 7); + + c7 = (lu | ru) & 0x7f; if (next_is_ext) { /* this is an extension character */ @@ -169,11 +179,9 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_ *(text++) = c8; } - nchars = text - text_buf_begin; - *text = '\0'; - return nchars; + return text - text_buf_begin; } int gsm_7bit_decode_n(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l) -- 2.5.0 From suraev at alumni.ntnu.no Thu Jan 21 16:16:56 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 21 Jan 2016 17:16:56 +0100 Subject: [PATCH] Fix bit reversion function Message-ID: <1453393016-20734-1-git-send-email-suraev@alumni.ntnu.no> From: Max Mark unsigned value as such. Fix unaligned access error revealed by asan on 32 bit builds. Sponsored-by: On-Waves ehf --- include/osmocom/core/bits.h | 2 +- src/bits.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/osmocom/core/bits.h b/include/osmocom/core/bits.h index 1587b05..d559185 100644 --- a/include/osmocom/core/bits.h +++ b/include/osmocom/core/bits.h @@ -75,7 +75,7 @@ uint32_t osmo_revbytebits_32(uint32_t x); uint32_t osmo_revbytebits_8(uint8_t x); /* \brief reverse the bits of each byte in a given buffer */ -void osmo_revbytebits_buf(uint8_t *buf, int len); +void osmo_revbytebits_buf(uint8_t *buf, unsigned int len); /*! \brief left circular shift * \param[in] in The 16 bit unsigned integer to be rotated diff --git a/src/bits.c b/src/bits.c index 01d7e73..e90bb71 100644 --- a/src/bits.c +++ b/src/bits.c @@ -206,10 +206,9 @@ uint32_t osmo_revbytebits_8(uint8_t x) * * This function reverses the bits in each byte of the buffer */ -void osmo_revbytebits_buf(uint8_t *buf, int len) +void osmo_revbytebits_buf(uint8_t *buf, unsigned int len) { - unsigned int i; - unsigned int unaligned_cnt; + unsigned int i, unaligned_cnt; int len_remain = len; unaligned_cnt = ((unsigned long)buf & 3); @@ -221,8 +220,7 @@ void osmo_revbytebits_buf(uint8_t *buf, int len) } for (i = unaligned_cnt; i + 3 < len; i += 4) { - uint32_t *cur = (uint32_t *) (buf + i); - *cur = osmo_revbytebits_32(*cur); + osmo_store32be(osmo_revbytebits_32(osmo_load32be(buf + i)), buf + i); len_remain -= 4; } -- 2.5.0 From holger at freyther.de Thu Jan 21 16:21:36 2016 From: holger at freyther.de (Holger Freyther) Date: Thu, 21 Jan 2016 17:21:36 +0100 Subject: [PATCH] Fix bit reversion function In-Reply-To: <1453393016-20734-1-git-send-email-suraev@alumni.ntnu.no> References: <1453393016-20734-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <73F16C07-CEBD-4CE5-970C-A595A519FB85@freyther.de> > On 21 Jan 2016, at 17:16, suraev at alumni.ntnu.no wrote: > > From: Max > > Mark unsigned value as such. > Fix unaligned access error revealed by asan on 32 bit builds. Linux vagrant-ubuntu-wily-64 4.2.0-23-generic #28-Ubuntu SMP Sun Dec 27 17:47:31 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux From holger at freyther.de Thu Jan 21 20:50:45 2016 From: holger at freyther.de (Holger Freyther) Date: Thu, 21 Jan 2016 21:50:45 +0100 Subject: [PATCH] Fix bit reversion function In-Reply-To: <1453393016-20734-1-git-send-email-suraev@alumni.ntnu.no> References: <1453393016-20734-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 21 Jan 2016, at 17:16, suraev at alumni.ntnu.no wrote: > > > -void osmo_revbytebits_buf(uint8_t *buf, int len); > +void osmo_revbytebits_buf(uint8_t *buf, unsigned int len); yes that makes sense but please do not mix bugfix and API change in one (unless the API change is the bugfix). E.g. 2/3 of the change is "noise" > @@ -221,8 +220,7 @@ void osmo_revbytebits_buf(uint8_t *buf, int len) > } > > for (i = unaligned_cnt; i + 3 < len; i += 4) { > - uint32_t *cur = (uint32_t *) (buf + i); > - *cur = osmo_revbytebits_32(*cur); > + osmo_store32be(osmo_revbytebits_32(osmo_load32be(buf + i)), buf + i); uint32_t cur; memcpy(&cur, buf + 1, sizeof(cur)); cur = osmo_revbytebits_32(cur); memcpy(buf + 1, &cur, sizeof(cur)); would be my approach. So let's compare it. Your code without the loop is here https://goo.gl/vD3kqQ and the memcpy variant is https://goo.gl/5kzTmx now if there would be a cloud microbenchmark we could resolve that once and for all. From suraev at alumni.ntnu.no Fri Jan 22 15:46:56 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Fri, 22 Jan 2016 16:46:56 +0100 Subject: [PATCH 2/5] Fix interface to consistently use unsigned int In-Reply-To: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453477619-27336-2-git-send-email-suraev@alumni.ntnu.no> From: Max Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 11 ++++++----- src/bitvec.c | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index 89eb784..e03b774 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -3,6 +3,7 @@ /* bit vector utility routines */ /* (C) 2009 by Harald Welte + * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved * @@ -66,12 +67,12 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum, enum bit_value bit); int bitvec_set_bit(struct bitvec *bv, enum bit_value bit); int bitvec_get_bit_high(struct bitvec *bv); -int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count); -int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count); -int bitvec_get_uint(struct bitvec *bv, int num_bits); +int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, unsigned int count); +int bitvec_set_uint(struct bitvec *bv, uint32_t in, unsigned int count); +int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits); int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val); int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); -int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count); -int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, int count); +int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); +int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count); /*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 726a768..8596d51 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -190,7 +190,7 @@ int bitvec_get_bit_high(struct bitvec *bv) * \param[in] bits array of \ref bit_value * \param[in] count number of bits to set */ -int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count) +int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, unsigned int count) { int i, rc; @@ -204,10 +204,10 @@ int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count) } /*! \brief set multiple bits (based on numeric value) at current pos */ -int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits) +int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) { - int i, rc; - + int rc; + unsigned i; for (i = 0; i < num_bits; i++) { int bit = 0; if (ui & (1 << (num_bits - i - 1))) @@ -221,7 +221,7 @@ int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits) } /*! \brief get multiple bits (based on numeric value) from current pos */ -int bitvec_get_uint(struct bitvec *bv, int num_bits) +int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) { int i; unsigned int ui = 0; @@ -269,7 +269,7 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, * \param[in] bytes array * \param[in] count number of bytes to copy */ -int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count) +int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count) { int byte_offs = bytenum_from_bitnum(bv->cur_bit); int bit_offs = bv->cur_bit % 8; @@ -304,7 +304,7 @@ int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count) * \param[in] bytes array * \param[in] count number of bytes to copy */ -int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, int count) +int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count) { int byte_offs = bytenum_from_bitnum(bv->cur_bit); int bit_offs = bv->cur_bit % 8; -- 2.5.0 From suraev at alumni.ntnu.no Fri Jan 22 15:46:55 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Fri, 22 Jan 2016 16:46:55 +0100 Subject: [PATCH 1/5] Ignore test binaries Message-ID: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> From: Max --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 598f88a..955634e 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ tests/strrb/strrb_test tests/vty/vty_test tests/gb/gprs_bssgp_test tests/smscb/gsm0341_test +tests/bitvec/bitvec_test +tests/gprs/gprs_test +tests/msgb/msgb_test utils/osmo-arfcn utils/osmo-auc-gen -- 2.5.0 From suraev at alumni.ntnu.no Fri Jan 22 15:46:57 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Fri, 22 Jan 2016 16:46:57 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> From: Max Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 8 ++++ src/bitvec.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index e03b774..ef65f9e 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -3,6 +3,7 @@ /* bit vector utility routines */ /* (C) 2009 by Harald Welte + * (C) 2012 Ivan Klyuchnikov * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved @@ -74,5 +75,12 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count); +struct bitvec * bitvec_alloc(unsigned int size); +void bitvec_free(struct bitvec *bv); +int bitvec_unhex(struct bitvec *bv, const char* src); +unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); +unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); +uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len); +int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len); /*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 8596d51..68b8d98 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -1,6 +1,7 @@ /* bit vector utility routines */ /* (C) 2009 by Harald Welte + * (C) 2012 Ivan Klyuchnikov * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved @@ -32,11 +33,15 @@ #include #include #include +#include +#include #include #define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit) +void *bv_tall_ctx; + static inline unsigned int bytenum_from_bitnum(unsigned int bitnum) { unsigned int bytenum = bitnum / 8; @@ -336,4 +341,91 @@ int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count bv->cur_bit += count * 8; return 0; } + +struct bitvec *bitvec_alloc(unsigned size) +{ + struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec); + bv->data_len = size; + bv->cur_bit = 0; + bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size); + return bv; +} + +void bitvec_free(struct bitvec *bv) +{ + talloc_free(bv->data); + talloc_free(bv); +} + +unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer) +{ + unsigned int i = 0; + for (i = 0; i < bv->data_len; i++) + { + buffer[i] = bv->data[i]; + } + return i; +} + +unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer) +{ + unsigned int i = 0; + for (i = 0; i < bv->data_len; i++) + { + bv->data[i] = buffer[i]; + } + return i; +} + + +int bitvec_unhex(struct bitvec *bv, const char* src) +{ + unsigned val; + unsigned write_index = 0; + unsigned digits = bv->data_len*2; + for (unsigned i=0; icur_bit = read_index; + + for (i = 0; i < len; i++) { + int bit = bitvec_get_bit_pos((const struct bitvec *)bv, bv->cur_bit); + if (bit < 0) + return bit; + if (bit) + ui |= ((uint64_t)1 << (len - i - 1)); + bv->cur_bit++; + } + read_index += len; + return ui; +} + + +int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len) +{ + unsigned int i; + int rc; + bv->cur_bit = write_index; + for (i = 0; i < len; i++) { + int bit = 0; + if (val & ((uint64_t)1 << (len - i - 1))) + bit = 1; + rc = bitvec_set_bit(bv, bit); + if (rc) + return rc; + } + write_index += len; + return 0; +} + /*! @} */ -- 2.5.0 From suraev at alumni.ntnu.no Fri Jan 22 15:46:58 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Fri, 22 Jan 2016 16:46:58 +0100 Subject: [PATCH 4/5] Expand bitvec interface In-Reply-To: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> From: Max Add bit filling, shifting and oter functions necessary for bit compression implementation. Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 10 +++- src/bitvec.c | 128 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 7 deletions(-) diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index ef65f9e..8078fc8 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -4,7 +4,7 @@ /* (C) 2009 by Harald Welte * (C) 2012 Ivan Klyuchnikov - * (C) 2015 by Sysmocom s.f.m.c. GmbH + * (C) 2015 by Sysmocom s.f.m.c. GmbH, Author: Max * * All Rights Reserved * @@ -41,6 +41,7 @@ */ #include +#include /*! \brief A single GSM bit * @@ -82,5 +83,12 @@ unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len); int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len); +int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill); +char bit_value_to_char(enum bit_value v); +void bitvec_to_string_r(const struct bitvec *bv, char *str); +void bitvec_zero(struct bitvec *bv); +unsigned bitvec_rl(const struct bitvec *bv, bool b); +void bitvec_shiftl(struct bitvec *bv, unsigned int n); +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits); /*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 68b8d98..b59d711 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -35,7 +35,9 @@ #include #include #include +#include +#include #include #define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit) @@ -225,6 +227,21 @@ int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) return 0; } +/*! \brief get multiple bits (num_bits) from beginning of vector (MSB side) */ +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits) +{ + if (num_bits > 15 || bv->cur_bit < num_bits) return -EINVAL; + + if (num_bits < 9) { + return bv->data[0] >> (8 - num_bits); + } + + uint8_t tmp[2]; + memcpy(tmp, bv->data, 2); + uint16_t t = osmo_load16be(tmp); + return t >> (16 - num_bits); +} + /*! \brief get multiple bits (based on numeric value) from current pos */ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) { @@ -243,17 +260,26 @@ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) return ui; } -/*! \brief pad all remaining bits up to num_bits */ -int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +/*! \brief fill num_bits with \fill starting from the current position + * returns 0 on success, negative otherwise (out of vector boundary) + */ +int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill) { - unsigned int i; - - for (i = bv->cur_bit; i <= up_to_bit; i++) - bitvec_set_bit(bv, L); + unsigned i, stop = bv->cur_bit + num_bits; + for (i = bv->cur_bit; i < stop; i++) + if (bitvec_set_bit(bv, fill) < 0) return -EINVAL; return 0; } +/*! \brief pad all remaining bits up to num_bits */ +int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +{ + int n = up_to_bit - bv->cur_bit + 1; + if (n < 1) return 0; + return bitvec_fill(bv, n, L); +} + /*! \brief find first bit set in bit vector */ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val) @@ -428,4 +454,94 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val return 0; } +/*! \brief convert enum to corresponding character */ +char bit_value_to_char(enum bit_value v) +{ + switch (v) { + case ZERO: return '0'; + case ONE: return '1'; + case L: return 'L'; + case H: return 'H'; + } + return 'X'; // make compiler happy +} + +/*! \brief prints bit vector to provided string + * It's caller's responcibility to ensure that we won't shoot him in the foot. + */ +void bitvec_to_string_r(const struct bitvec *bv, char *str) +{ + unsigned i, pos = 0; + char *cur = str; + for (i = 0; i < bv->cur_bit; i++) { + if (0 == i % 8) *cur++ = ' '; + *cur++ = bit_value_to_char(bitvec_get_bit_pos(bv, i)); + pos++; + } + *cur = 0; +} + +/* we assume that x have at least 1 non-b bit */ +static inline unsigned _leading_bits(uint8_t x, bool b) +{ + if (b) { + if (x < 0x80) return 0; + if (x < 0xC0) return 1; + if (x < 0xE0) return 2; + if (x < 0xF0) return 3; + if (x < 0xF8) return 4; + if (x < 0xFC) return 5; + if (x < 0xFE) return 6; + } else { + if (x > 0x7F) return 0; + if (x > 0x3F) return 1; + if (x > 0x1F) return 2; + if (x > 0xF) return 3; + if (x > 7) return 4; + if (x > 3) return 5; + if (x > 1) return 6; + } + return 7; +} +/*! \brief force bit vector to all 0 and current bit to the beginnig of the vector */ +void bitvec_zero(struct bitvec *bv) +{ + bv->cur_bit = 0; + memset(bv->data, 0, bv->data_len); +} + +/*! \brief Return number (bits) of uninterrupted run of \b in \bv starting from the MSB */ +unsigned bitvec_rl(const struct bitvec *bv, bool b) +{ + unsigned i; + for (i = 0; i < (bv->cur_bit % 8 ? bv->cur_bit / 8 + 1 : bv->cur_bit / 8); i++) { + if ( (b ? 0xFF : 0) != bv->data[i]) return i * 8 + _leading_bits(bv->data[i], b); + } + + return bv->cur_bit; +} + +/*! \brief Shifts bitvec to the left, n MSB bits lost */ +void bitvec_shiftl(struct bitvec *bv, unsigned n) +{ + if (0 == n) return; + if (n >= bv->cur_bit) { + bitvec_zero(bv); + return; + } + + memmove(bv->data, bv->data + n / 8, bv->data_len - n / 8); + + uint8_t tmp[2]; + unsigned i; + for (i = 0; i < bv->data_len - 2; i++) { + uint16_t t = osmo_load16be(bv->data + i); + osmo_store16be(t << (n % 8), &tmp); + bv->data[i] = tmp[0]; + } + + bv->data[bv->data_len - 1] <<= (n % 8); + bv->cur_bit -= n; +} + /*! @} */ -- 2.5.0 From suraev at alumni.ntnu.no Fri Jan 22 15:46:59 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Fri, 22 Jan 2016 16:46:59 +0100 Subject: [PATCH 5/5] Expand bitvec test harness In-Reply-To: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453477619-27336-5-git-send-email-suraev@alumni.ntnu.no> From: Max Sponsored-by: On-Waves ehf --- tests/bitvec/bitvec_test.c | 143 +++++++++++++++++++++++++++++++++++++++++++- tests/bitvec/bitvec_test.ok | 119 ++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 2 deletions(-) diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c index 624e334..c31e5df 100644 --- a/tests/bitvec/bitvec_test.c +++ b/tests/bitvec/bitvec_test.c @@ -3,9 +3,82 @@ #include #include #include +#include +#include +#include #include #include +#include + +#define BIN_PATTERN "%d%d%d%d%d%d%d%d" +#define BIN(byte) \ + (byte & 0x80 ? 1 : 0), \ + (byte & 0x40 ? 1 : 0), \ + (byte & 0x20 ? 1 : 0), \ + (byte & 0x10 ? 1 : 0), \ + (byte & 0x08 ? 1 : 0), \ + (byte & 0x04 ? 1 : 0), \ + (byte & 0x02 ? 1 : 0), \ + (byte & 0x01 ? 1 : 0) + +static char lol[1024]; // we pollute this with printed vectors +static inline void test_rl(const struct bitvec *bv) +{ + bitvec_to_string_r(bv, lol); + printf("%s [%d] RL0=%d, RL1=%d\n", lol, bv->cur_bit, bitvec_rl(bv, false), bitvec_rl(bv, true)); +} + +static inline void test_shift(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + printf("%s << %d:\n", lol, n); + bitvec_shiftl(bv, n); + bitvec_to_string_r(bv, lol); + printf("%s\n", lol); +} + +static inline void test_get(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + printf("%s [%d]", lol, bv->cur_bit); + int16_t x = bitvec_get_int16_msb(bv, n); + uint8_t tmp[2]; + osmo_store16be(x, &tmp); + printf(" -> %d (%u bit) ["BIN_PATTERN" "BIN_PATTERN"]:\n", x, n, BIN(tmp[0]), BIN(tmp[1])); + bitvec_to_string_r(bv, lol); + printf("%s [%d]\n", lol, bv->cur_bit); +} + +static inline void test_fill(struct bitvec *bv, unsigned n, enum bit_value val) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int fi = bitvec_fill(bv, n, val); + printf("%c> FILL %s [%d] -%d-> [%d]:\n", bit_value_to_char(val), lol, bvlen, n, fi); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +} + +static inline void test_spare(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int sp = bitvec_spare_padding(bv, n); + printf("%c> SPARE %s [%d] -%d-> [%d]:\n", bit_value_to_char(L), lol, bvlen, n, sp); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +} + +static inline void test_set(struct bitvec *bv, enum bit_value bit) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int set = bitvec_set_bit(bv, bit); + printf("%c> SET %s [%d] ++> [%d]:\n", bit_value_to_char(bit), lol, bvlen, set); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +} static void test_byte_ops() { @@ -33,7 +106,7 @@ static void test_byte_ops() rc = bitvec_set_uint(&bv, 0x7e, 8); OSMO_ASSERT(rc >= 0); - fprintf(stderr, "bitvec: %s\n", osmo_hexdump(bv.data, bv.data_len)); + printf("bitvec: %s\n", osmo_hexdump(bv.data, bv.data_len)); /* Read from bitvec */ memset(out, 0xff, sizeof(out)); @@ -45,7 +118,7 @@ static void test_byte_ops() rc = bitvec_get_uint(&bv, 8); OSMO_ASSERT(rc == 0x7e); - fprintf(stderr, "out: %s\n", osmo_hexdump(out, sizeof(out))); + printf("out: %s\n", osmo_hexdump(out, sizeof(out))); OSMO_ASSERT(out[0] == 0xff); OSMO_ASSERT(out[in_size+1] == 0xff); @@ -57,6 +130,72 @@ static void test_byte_ops() int main(int argc, char **argv) { + srand(time(NULL)); + + struct bitvec bv; + uint8_t i = 8, test[i]; + + memset(test, 0, i); + bv.data_len = i; + bv.data = test; + bv.cur_bit = 0; + + printf("test shifting...\n"); + + bitvec_set_uint(&bv, 0x0E, 7); + test_shift(&bv, 3); + test_shift(&bv, 17); + bitvec_set_uint(&bv, 0, 32); + bitvec_set_uint(&bv, 0x0A, 7); + test_shift(&bv, 24); + + printf("checking RL functions...\n"); + + bitvec_zero(&bv); + test_rl(&bv); + bitvec_set_uint(&bv, 0x000F, 32); + test_rl(&bv); + bitvec_shiftl(&bv, 18); + test_rl(&bv); + bitvec_set_uint(&bv, 0x0F, 8); + test_rl(&bv); + bitvec_zero(&bv); + bitvec_set_uint(&bv, 0xFF, 8); + test_rl(&bv); + bitvec_set_uint(&bv, 0xFE, 7); + test_rl(&bv); + bitvec_set_uint(&bv, 0, 17); + test_rl(&bv); + bitvec_shiftl(&bv, 18); + test_rl(&bv); + + printf("probing bit access...\n"); + + bitvec_zero(&bv); + bitvec_set_uint(&bv, 0x3747817, 32); + bitvec_shiftl(&bv, 10); + + test_get(&bv, 2); + test_get(&bv, 7); + test_get(&bv, 9); + test_get(&bv, 13); + test_get(&bv, 16); + test_get(&bv, 42); + + printf("feeling bit fills...\n"); + + test_set(&bv, ONE); + test_fill(&bv, 3, ZERO); + test_spare(&bv, 38); + test_spare(&bv, 43); + test_spare(&bv, 1); + test_spare(&bv, 7); + test_fill(&bv, 5, ONE); + test_fill(&bv, 3, L); + + printf("byte me...\n"); + test_byte_ops(); + return 0; } diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok index 1f329af..38575f7 100644 --- a/tests/bitvec/bitvec_test.ok +++ b/tests/bitvec/bitvec_test.ok @@ -1,2 +1,121 @@ +test shifting... + 0001110 << 3: + 1110 + 1110 << 17: + + 00000000 00000000 00000000 00000000 0001010 << 24: + 00000000 0001010 +checking RL functions... + [0] RL0=0, RL1=0 + 00000000 00000000 00000000 00001111 [32] RL0=28, RL1=0 + 00000000 001111 [14] RL0=10, RL1=0 + 00000000 00111100 001111 [22] RL0=10, RL1=0 + 11111111 [8] RL0=0, RL1=8 + 11111111 1111110 [15] RL0=0, RL1=14 + 11111111 11111100 00000000 00000000 [32] RL0=0, RL1=14 + 00000000 000000 [14] RL0=14, RL1=0 +probing bit access... + 11010001 11100000 010111 [22] -> 3 (2 bit) [00000000 00000011]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 104 (7 bit) [00000000 01101000]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 419 (9 bit) [00000001 10100011]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 6716 (13 bit) [00011010 00111100]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> -22 (16 bit) [11111111 11101010]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> -22 (42 bit) [11111111 11101010]: + 11010001 11100000 010111 [22] +feeling bit fills... +1> SET 11010001 11100000 010111 [22] ++> [0]: + 11010001 11100000 0101111 [23] + +0> FILL 11010001 11100000 0101111 [23] -3-> [0]: + 11010001 11100000 01011110 00 [26] + +L> SPARE 11010001 11100000 01011110 00 [26] -38-> [0]: + 11010001 11100000 01011110 00101011 0010101 [39] + +L> SPARE 11010001 11100000 01011110 00101011 0010101 [39] -43-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +L> SPARE 11010001 11100000 01011110 00101011 00101011 0010 [44] -1-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +L> SPARE 11010001 11100000 01011110 00101011 00101011 0010 [44] -7-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +1> FILL 11010001 11100000 01011110 00101011 00101011 0010 [44] -5-> [0]: + 11010001 11100000 01011110 00101011 00101011 00101111 1 [49] + +L> FILL 11010001 11100000 01011110 00101011 00101011 00101111 1 [49] -3-> [0]: + 11010001 11100000 01011110 00101011 00101011 00101111 1010 [52] + +byte me... === start test_byte_ops === +bitvec: 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff === end test_byte_ops === -- 2.5.0 From suraev at alumni.ntnu.no Fri Jan 22 15:49:59 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Fri, 22 Jan 2016 16:49:59 +0100 Subject: [PATCH 1/5] Ignore test binaries In-Reply-To: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <56A24FA7.2030704@alumni.ntnu.no> This is v3 version of bitvec patchset. Difference from previous submissions: - fix for build issue with asan - split into several commits - added corresponding functions from osmo-pcu cheers, Max. From holger at freyther.de Fri Jan 22 21:45:11 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 22 Jan 2016 22:45:11 +0100 Subject: [PATCH 2/5] Fix interface to consistently use unsigned int In-Reply-To: <1453477619-27336-2-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-2-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 22 Jan 2016, at 16:46, suraev at alumni.ntnu.no wrote: > Hi! > /* (C) 2009 by Harald Welte > + * (C) 2015 by Sysmocom s.f.m.c. GmbH I think it will be difficult to claim s/int/unsigned int/ as copyright. I can amend the commit to remove the copyright notice again. From holger at freyther.de Fri Jan 22 21:48:30 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 22 Jan 2016 22:48:30 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> Message-ID: <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> > On 22 Jan 2016, at 16:46, suraev at alumni.ntnu.no wrote: > > > @@ -74,5 +75,12 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value > int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); > int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); > int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count); > +struct bitvec * bitvec_alloc(unsigned int size); coding style to have ' * ' in the middle of nowwhere > #define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit) > > +void *bv_tall_ctx; static? how is the talloc context "rooted" so that it will show up in the leak detection? > +struct bitvec *bitvec_alloc(unsigned size) > +{ > + struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec); > + bv->data_len = size; > + bv->cur_bit = 0; > + bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size); > + return bv; bv is a talloc context itself so it should be used to create data instead of the global one. > +unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer) > +{ > + unsigned int i = 0; > + for (i = 0; i < bv->data_len; i++) > + { coding style for the '{' and in other methods too. From suraev at alumni.ntnu.no Mon Jan 25 12:28:36 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Mon, 25 Jan 2016 13:28:36 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> Message-ID: <56A614F4.3000903@alumni.ntnu.no> You're right, it does not belong to the lib. Fixed it alongside with style comments in attached patch. cheers, Max. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Add-bitvec-related-functions-from-Osmo-PCU.patch Type: text/x-patch Size: 4242 bytes Desc: not available URL: From holger at freyther.de Mon Jan 25 15:23:57 2016 From: holger at freyther.de (Holger Freyther) Date: Mon, 25 Jan 2016 16:23:57 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <56A614F4.3000903@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> <56A614F4.3000903@alumni.ntnu.no> Message-ID: <68858672-9913-4510-A275-245C4891485F@freyther.de> > On 25 Jan 2016, at 13:28, Max (?) wrote: > > <0001-Add-bitvec-related-functions-from-Osmo-PCU.patch> +struct bitvec *bitvec_alloc(unsigned int size, TALLOC_CTX * bvctx) +{ + struct bitvec *bv = talloc_zero(bvctx, struct bitvec); + bv->data_len = size; + bv->cur_bit = 0; + bv->data = talloc_zero_array(bvctx, uint8_t, size); + return bv; +} talloc has hierachies. So we pass the context into it but bv->data should be a child of "data". As a library function it needs to handle OOM as well. bv = talloc_zero(bvctx, struct bitvec); if (!bv) return NULL; bv->data_len = size; .. bv->data = talloc_zero_array(bv, uint8_t, size); if (!bv->data) { talloc_free(bv); return NULL; } return bv holger From suraev at alumni.ntnu.no Mon Jan 25 16:01:28 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Mon, 25 Jan 2016 17:01:28 +0100 Subject: [PATCH 2/2] Get rid of duplicated timer code In-Reply-To: <1453737688-27611-1-git-send-email-suraev@alumni.ntnu.no> References: <1453737688-27611-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453737688-27611-2-git-send-email-suraev@alumni.ntnu.no> From: Max Sponsored-by: On-Waves ehf --- src/Makefile.am | 2 - src/gprs_rlcmac.h | 1 - src/gsm_timer.cpp | 238 ------------------------------------------------------ src/gsm_timer.h | 84 ------------------- src/pcu_main.cpp | 8 +- src/tbf.h | 2 +- 6 files changed, 5 insertions(+), 330 deletions(-) delete mode 100644 src/gsm_timer.cpp delete mode 100644 src/gsm_timer.h diff --git a/src/Makefile.am b/src/Makefile.am index 6428bef..e345f26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,6 @@ libgprs_la_SOURCES = \ gprs_rlcmac_ts_alloc.cpp \ gprs_ms.cpp \ gprs_ms_storage.cpp \ - gsm_timer.cpp \ bitvector.cpp \ pcu_l1_if.cpp \ pcu_vty.c \ @@ -79,7 +78,6 @@ noinst_HEADERS = \ gprs_ms_storage.h \ pcuif_proto.h \ pcu_l1_if.h \ - gsm_timer.h \ bitvector.h \ pcu_vty.h \ pcu_vty_functions.h \ diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index f193dfa..ed1e529 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -24,7 +24,6 @@ #ifdef __cplusplus #include #include -#include extern "C" { #include diff --git a/src/gsm_timer.cpp b/src/gsm_timer.cpp deleted file mode 100644 index d3c59cb..0000000 --- a/src/gsm_timer.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* gsm_timer.cpp - * - * Copyright (C) 2012 Ivan Klyuchnikov - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* These store the amount of frame number that we wait until next timer expires. */ -static int nearest; -static int *nearest_p; - -/*! \addtogroup gsm_timer - * @{ - */ - -/*! \file gsm_timer.cpp - */ - -#include -#include -#include -#include -#include -#include - - -static struct rb_root timer_root = RB_ROOT; - -/* - * TODO: make this depend on the BTS. This means that - * all time functions schedule based on the BTS they - * are scheduled on. - */ -static int get_current_fn() -{ - return BTS::main_bts()->current_frame_number(); -} - -static void __add_gsm_timer(struct osmo_gsm_timer_list *timer) -{ - struct rb_node **new_node = &(timer_root.rb_node); - struct rb_node *parent = NULL; - - while (*new_node) { - struct osmo_gsm_timer_list *this_timer; - - this_timer = container_of(*new_node, struct osmo_gsm_timer_list, node); - - parent = *new_node; - if (timer->fn < this_timer->fn) - new_node = &((*new_node)->rb_left); - else - new_node = &((*new_node)->rb_right); - } - - rb_link_node(&timer->node, parent, new_node); - rb_insert_color(&timer->node, &timer_root); -} - -/*! \brief add a new timer to the timer management - * \param[in] timer the timer that should be added - */ -void osmo_gsm_timer_add(struct osmo_gsm_timer_list *timer) -{ - osmo_gsm_timer_del(timer); - timer->active = 1; - INIT_LLIST_HEAD(&timer->list); - __add_gsm_timer(timer); -} - -/*! \brief schedule a gsm timer at a given future relative time - * \param[in] timer the to-be-added timer - * \param[in] number of frames from now - * - * This function can be used to (re-)schedule a given timer at a - * specified number of frames in the future. It will - * internally add it to the timer management data structures, thus - * osmo_timer_add() is automatically called. - */ -void -osmo_gsm_timer_schedule(struct osmo_gsm_timer_list *timer, int fn) -{ - int current_fn; - - current_fn = get_current_fn(); - timer->fn = current_fn + fn; - osmo_gsm_timer_add(timer); -} - -/*! \brief delete a gsm timer from timer management - * \param[in] timer the to-be-deleted timer - * - * This function can be used to delete a previously added/scheduled - * timer from the timer management code. - */ -void osmo_gsm_timer_del(struct osmo_gsm_timer_list *timer) -{ - if (timer->active) { - timer->active = 0; - rb_erase(&timer->node, &timer_root); - /* make sure this is not already scheduled for removal. */ - if (!llist_empty(&timer->list)) - llist_del_init(&timer->list); - } -} - -/*! \brief check if given timer is still pending - * \param[in] timer the to-be-checked timer - * \return 1 if pending, 0 otherwise - * - * This function can be used to determine whether a given timer - * has alredy expired (returns 0) or is still pending (returns 1) - */ -int osmo_gsm_timer_pending(struct osmo_gsm_timer_list *timer) -{ - return timer->active; -} - -/* - * if we have a nearest frame number return the delta between the current - * FN and the FN of the nearest timer. - * If the nearest timer timed out return NULL and then we will - * dispatch everything after the select - */ -int *osmo_gsm_timers_nearest(void) -{ - /* nearest_p is exactly what we need already: NULL if nothing is - * waiting, {0,0} if we must dispatch immediately, and the correct - * delay if we need to wait */ - return nearest_p; -} - -static void update_nearest(int *cand, int *current) -{ - if (*cand != LONG_MAX) { - if (*cand > *current) - nearest = *cand - *current; - else { - /* loop again inmediately */ - nearest = 0; - } - nearest_p = &nearest; - } else { - nearest_p = NULL; - } -} - -/* - * Find the nearest FN and update s_nearest_time - */ -void osmo_gsm_timers_prepare(void) -{ - struct rb_node *node; - int current_fn; - - current_fn = get_current_fn(); - - node = rb_first(&timer_root); - if (node) { - struct osmo_gsm_timer_list *this_timer; - this_timer = container_of(node, struct osmo_gsm_timer_list, node); - update_nearest(&this_timer->fn, ¤t_fn); - } else { - nearest_p = NULL; - } -} - -/* - * fire all timers... and remove them - */ -int osmo_gsm_timers_update(void) -{ - int current_fn; - struct rb_node *node; - struct llist_head timer_eviction_list; - struct osmo_gsm_timer_list *this_timer; - int work = 0; - - current_fn = get_current_fn(); - - INIT_LLIST_HEAD(&timer_eviction_list); - for (node = rb_first(&timer_root); node; node = rb_next(node)) { - this_timer = container_of(node, struct osmo_gsm_timer_list, node); - - if (this_timer->fn > current_fn) - break; - - llist_add(&this_timer->list, &timer_eviction_list); - } - - /* - * The callbacks might mess with our list and in this case - * even llist_for_each_entry_safe is not safe to use. To allow - * osmo_gsm_timer_del to be called from within the callback we need - * to restart the iteration for each element scheduled for removal. - * - * The problematic scenario is the following: Given two timers A - * and B that have expired at the same time. Thus, they are both - * in the eviction list in this order: A, then B. If we remove - * timer B from the A's callback, we continue with B in the next - * iteration step, leading to an access-after-release. - */ -restart: - llist_for_each_entry(this_timer, &timer_eviction_list, list) { - osmo_gsm_timer_del(this_timer); - this_timer->cb(this_timer->data); - work = 1; - goto restart; - } - - return work; -} - -int osmo_gsm_timers_check(void) -{ - struct rb_node *node; - int i = 0; - - for (node = rb_first(&timer_root); node; node = rb_next(node)) { - i++; - } - return i; -} - -/*! }@ */ - diff --git a/src/gsm_timer.h b/src/gsm_timer.h deleted file mode 100644 index fc42caf..0000000 --- a/src/gsm_timer.h +++ /dev/null @@ -1,84 +0,0 @@ -/* gsm_timer.h - * - * Copyright (C) 2012 Ivan Klyuchnikov - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*! \defgroup timer GSM timers - * @{ - */ - -/*! \file gsm_timer.h - * \brief GSM timer handling routines - */ -#ifndef GSM_TIMER_H -#define GSM_TIMER_H - -extern "C" { -#include -#include -} -/** - * Timer management: - * - Create a struct osmo_gsm_timer_list - * - Fill out timeout and use add_gsm_timer or - * use schedule_gsm_timer to schedule a timer in - * x frames from now... - * - Use del_gsm_timer to remove the timer - * - * Internally: - * - We hook into select.c to give a frame number of the - * nearest timer. On already passed timers we give - * it a 0 to immediately fire after the select. - * - update_gsm_timers will call the callbacks and remove - * the timers. - * - */ -/*! \brief A structure representing a single instance of a gsm timer */ -struct osmo_gsm_timer_list { - struct rb_node node; /*!< \brief rb-tree node header */ - struct llist_head list; /*!< \brief internal list header */ - int fn; /*!< \brief expiration frame number */ - unsigned int active : 1; /*!< \brief is it active? */ - - void (*cb)(void*); /*!< \brief call-back called at timeout */ - void *data; /*!< \brief user data for callback */ -}; - -/** - * timer management - */ - -void osmo_gsm_timer_add(struct osmo_gsm_timer_list *timer); - -void osmo_gsm_timer_schedule(struct osmo_gsm_timer_list *timer, int fn); - -void osmo_gsm_timer_del(struct osmo_gsm_timer_list *timer); - -int osmo_gsm_timer_pending(struct osmo_gsm_timer_list *timer); - - -/* - * internal timer list management - */ -int *osmo_gsm_timers_nearest(void); -void osmo_gsm_timers_prepare(void); -int osmo_gsm_timers_update(void); -int osmo_gsm_timers_check(void); - -/*! }@ */ - -#endif // GSM_TIMER_H diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 77e1082..a9f9df1 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ extern "C" { #include #include #include +#include } extern struct gprs_nsvc *nsvc; @@ -256,9 +256,9 @@ int main(int argc, char *argv[]) } while (!quit) { - osmo_gsm_timers_check(); - osmo_gsm_timers_prepare(); - osmo_gsm_timers_update(); + osmo_timers_check(); + osmo_timers_prepare(); + osmo_timers_update(); osmo_select_main(0); } diff --git a/src/tbf.h b/src/tbf.h index a3a2eeb..411d113 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -202,7 +202,7 @@ struct gprs_rlcmac_tbf { unsigned int T; /* Txxxx number */ unsigned int num_T_exp; /* number of consecutive T expirations */ - struct osmo_gsm_timer_list gsm_timer; + struct osmo_timer_list gsm_timer; unsigned int fT; /* fTxxxx number */ unsigned int num_fT_exp; /* number of consecutive fT expirations */ -- 2.5.0 From suraev at alumni.ntnu.no Mon Jan 25 16:01:27 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Mon, 25 Jan 2016 17:01:27 +0100 Subject: [PATCH 1/2] Add missing build leftovers to .gitignore Message-ID: <1453737688-27611-1-git-send-email-suraev@alumni.ntnu.no> From: Max --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6cc9aa5..46ddeb3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ Makefile.in Makefile .deps +compile aclocal.m4 autom4te.cache config.log @@ -42,3 +43,5 @@ tests/codel/codel_test tests/emu/pcu_emu tests/testsuite tests/testsuite.log +tests/edge/EdgeTest +tests/llc/LlcTest -- 2.5.0 From suraev at alumni.ntnu.no Mon Jan 25 16:26:53 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Mon, 25 Jan 2016 17:26:53 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <68858672-9913-4510-A275-245C4891485F@freyther.de> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> <56A614F4.3000903@alumni.ntnu.no> <68858672-9913-4510-A275-245C4891485F@freyther.de> Message-ID: <56A64CCD.8090403@alumni.ntnu.no> v2 attached - added hierarchical allocation. cheers, Max. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Add-bitvec-related-functions-from-Osmo-PCU.patch Type: text/x-patch Size: 4364 bytes Desc: not available URL: From nhofmeyr at sysmocom.de Mon Jan 25 16:55:21 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 25 Jan 2016 17:55:21 +0100 Subject: libosmo-netif branch sysmocom/sctp Message-ID: <20160125165521.GA12986@dub6> Hey Daniel, can we merge libosmo-netif branch sysmocom/sctp to master? ("stream.c: Handle SCTP in osmo_stream_srv_recv()") I'm rebasing it to kill a coverity warning (fixed by Holger). Thx, ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Mon Jan 25 21:05:35 2016 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 25 Jan 2016 22:05:35 +0100 Subject: [PATCH] gsm0408: Provide unique strings for the gsm 04.08 message Message-ID: <1453755935-8753-1-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther At Rhizomatica we see that some GSM 04.08 messages are leaked and have no other indication if that is Call Control, SMS or something else. --- openbsc/include/openbsc/gsm_04_08.h | 4 +-- openbsc/src/gprs/gb_proxy.c | 4 +-- openbsc/src/gprs/gprs_gmm.c | 36 +++++++++++----------- openbsc/src/libbsc/gsm_04_08_utils.c | 16 +++++----- openbsc/src/libmsc/gsm_04_08.c | 58 +++++++++++++++++------------------ openbsc/src/libmsc/gsm_04_80.c | 6 ++-- openbsc/src/osmo-bsc/osmo_bsc_bssap.c | 2 +- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 02d67f7..fd0b89d 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -19,10 +19,10 @@ struct amr_mode; #define GSM48_ALLOC_SIZE 2048 #define GSM48_ALLOC_HEADROOM 256 -static inline struct msgb *gsm48_msgb_alloc(void) +static inline struct msgb *gsm48_msgb_alloc_name(const char *name) { return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, - "GSM 04.08"); + name); } static inline int get_radio_link_timeout(struct gsm48_cell_options *cell_options) diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 6cad651..9551335 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -393,7 +393,7 @@ static void gbproxy_acquire_imsi(struct gbproxy_peer *peer, struct msgb *idreq_msg; /* Send IDENT REQ */ - idreq_msg = gsm48_msgb_alloc(); + idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI"); gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI); gbproxy_gsm48_to_peer(peer, link_info, bvci, idreq_msg); } @@ -405,7 +405,7 @@ static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer, struct msgb *detacc_msg; /* Send DETACH ACC */ - detacc_msg = gsm48_msgb_alloc(); + detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC"); gprs_put_mo_detach_acc(detacc_msg); gbproxy_gsm48_to_peer(peer, link_info, bvci, detacc_msg); } diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 115e898..7d3e3de 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -199,7 +199,7 @@ static int _tx_status(struct msgb *msg, uint8_t cause, static int gsm48_tx_gmm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 GMM STATUS"); mmctx2msgid(msg, mmctx); return _tx_status(msg, cause, mmctx, 0); @@ -207,7 +207,7 @@ static int gsm48_tx_gmm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause) static int gsm48_tx_sm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SM STATUS"); mmctx2msgid(msg, mmctx); return _tx_status(msg, cause, mmctx, 1); @@ -238,7 +238,7 @@ static int _tx_detach_req(struct msgb *msg, uint8_t detach_type, uint8_t cause, static int gsm48_tx_gmm_detach_req(struct sgsn_mm_ctx *mmctx, uint8_t detach_type, uint8_t cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET REQ"); mmctx2msgid(msg, mmctx); return _tx_detach_req(msg, detach_type, cause, mmctx); @@ -247,7 +247,7 @@ static int gsm48_tx_gmm_detach_req(struct sgsn_mm_ctx *mmctx, static int gsm48_tx_gmm_detach_req_oldmsg(struct msgb *oldmsg, uint8_t detach_type, uint8_t cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET OLD"); gmm_copy_id(msg, oldmsg); return _tx_detach_req(msg, detach_type, cause, NULL); @@ -279,7 +279,7 @@ static struct gsm48_qos default_qos = { /* Chapter 9.4.2: Attach accept */ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT ACK"); struct gsm48_hdr *gh; struct gsm48_attach_ack *aa; uint8_t *mid; @@ -350,14 +350,14 @@ static int _tx_gmm_att_rej(struct msgb *msg, uint8_t gmm_cause, static int gsm48_tx_gmm_att_rej_oldmsg(const struct msgb *old_msg, uint8_t gmm_cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ OLD"); gmm_copy_id(msg, old_msg); return _tx_gmm_att_rej(msg, gmm_cause, NULL); } static int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm, uint8_t gmm_cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ"); mmctx2msgid(msg, mm); return _tx_gmm_att_rej(msg, gmm_cause, mm); } @@ -382,7 +382,7 @@ static int _tx_detach_ack(struct msgb *msg, uint8_t force_stby, static int gsm48_tx_gmm_det_ack(struct sgsn_mm_ctx *mm, uint8_t force_stby) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK"); mmctx2msgid(msg, mm); return _tx_detach_ack(msg, force_stby, mm); @@ -390,7 +390,7 @@ static int gsm48_tx_gmm_det_ack(struct sgsn_mm_ctx *mm, uint8_t force_stby) static int gsm48_tx_gmm_det_ack_oldmsg(struct msgb *oldmsg, uint8_t force_stby) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK OLD"); gmm_copy_id(msg, oldmsg); return _tx_detach_ack(msg, force_stby, NULL); @@ -399,7 +399,7 @@ static int gsm48_tx_gmm_det_ack_oldmsg(struct msgb *oldmsg, uint8_t force_stby) /* Transmit Chapter 9.4.12 Identity Request */ static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ"); struct gsm48_hdr *gh; LOGMMCTXP(LOGL_DEBUG, mm, "<- GPRS IDENTITY REQUEST: mi_type=%s\n", @@ -420,7 +420,7 @@ static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type) static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rand, uint8_t key_seq, uint8_t algo) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REQ"); struct gsm48_hdr *gh; struct gsm48_auth_ciph_req *acreq; uint8_t *m_rand, *m_cksn; @@ -458,7 +458,7 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rand, /* Section 9.4.11: Authentication and Ciphering Reject */ static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REJ"); struct gsm48_hdr *gh; LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS AUTH AND CIPH REJECT\n"); @@ -1020,7 +1020,7 @@ static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) /* Chapter 9.4.15: Routing area update accept */ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UPD ACK"); struct gsm48_hdr *gh; struct gsm48_ra_upd_ack *rua; uint8_t *mid; @@ -1067,7 +1067,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm) /* Chapter 9.4.17: Routing area update reject */ static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RA UPD REJ"); struct gsm48_hdr *gh; LOGP(DMM, LOGL_NOTICE, "<- ROUTING AREA UPDATE REJECT\n"); @@ -1502,7 +1502,7 @@ static void msgb_put_pdp_addr_ppp(struct msgb *msg) /* Section 9.5.2: Ativate PDP Context Accept */ int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP ACC"); struct gsm48_hdr *gh; uint8_t transaction_id = pdp->ti ^ 0x8; /* flip */ @@ -1546,7 +1546,7 @@ int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp) int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, uint8_t cause, uint8_t pco_len, uint8_t *pco_v) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP REJ"); struct gsm48_hdr *gh; uint8_t transaction_id = tid ^ 0x8; /* flip */ @@ -1569,7 +1569,7 @@ int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid, uint8_t sm_cause) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET REQ"); struct gsm48_hdr *gh; uint8_t transaction_id = tid ^ 0x8; /* flip */ @@ -1595,7 +1595,7 @@ int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause) /* Section 9.5.9: Deactivate PDP Context Accept */ static int _gsm48_tx_gsm_deact_pdp_acc(struct sgsn_mm_ctx *mm, uint8_t tid) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET ACC"); struct gsm48_hdr *gh; uint8_t transaction_id = tid ^ 0x8; /* flip */ diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c index 4901912..8c6dbef 100644 --- a/openbsc/src/libbsc/gsm_04_08_utils.c +++ b/openbsc/src/libbsc/gsm_04_08_utils.c @@ -224,7 +224,7 @@ static void mr_config_for_ms(struct gsm_lchan *lchan, struct msgb *msg) /* 7.1.7 and 9.1.7: RR CHANnel RELease */ int gsm48_send_rr_release(struct gsm_lchan *lchan) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); uint8_t *cause; @@ -314,7 +314,7 @@ int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, /* Chapter 9.1.9: Ciphering Mode Command */ int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CIPH"); struct gsm48_hdr *gh; uint8_t ciph_mod_set; @@ -410,7 +410,7 @@ int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct am int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, uint8_t power_command, uint8_t ho_ref) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 HO CMD"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *) msgb_put(msg, sizeof(*ho)); @@ -449,7 +449,7 @@ int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, /* Chapter 9.1.2: Assignment Command */ int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_command) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ASS CMD"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_ass_cmd *ass = (struct gsm48_ass_cmd *) msgb_put(msg, sizeof(*ass)); @@ -490,7 +490,7 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, /* 9.1.5 Channel mode modify: Modify the mode on the MS side */ int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, uint8_t mode) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CHN MOD"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_chan_mode_modify *cmm = (struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm)); @@ -650,7 +650,7 @@ struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value) struct msgb *msg; struct gsm48_hdr *gh; - msg = gsm48_msgb_alloc(); + msg = gsm48_msgb_alloc_name("GSM 04.08 SERV REJ"); if (!msg) return NULL; @@ -667,7 +667,7 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) struct gsm48_hdr *gh; struct msgb *msg; - msg = gsm48_msgb_alloc(); + msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD REJ"); if (!msg) return NULL; @@ -681,7 +681,7 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) /* 9.2.5 CM service accept */ int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); msg->lchan = conn->lchan; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 9d7e2aa..d9d7390 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -458,7 +458,7 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause) static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn) { struct gsm_bts *bts = conn->bts; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC"); struct gsm48_hdr *gh; struct gsm48_loc_area_id *lai; uint8_t *mid; @@ -494,7 +494,7 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn) /* Transmit Chapter 9.2.10 Identity Request */ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id_type) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ"); struct gsm48_hdr *gh; msg->lchan = conn->lchan; @@ -707,7 +707,7 @@ static uint8_t bcdify(uint8_t value) /* Section 9.2.15a */ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) { - struct msgb *msg = gsm48_msgb_alloc(); + 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_bts *bts = conn->bts; @@ -855,7 +855,7 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) /* Section 9.2.2 */ int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, int key_seq) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH REQ"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_auth_req *ar = (struct gsm48_auth_req *) msgb_put(msg, sizeof(*ar)); @@ -1261,7 +1261,7 @@ static int gsm0408_rcv_rr(struct gsm_subscriber_connection *conn, struct msgb *m int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id, uint8_t apdu_len, const uint8_t *apdu) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF"); struct gsm48_hdr *gh; msg->lchan = conn->lchan; @@ -1300,7 +1300,7 @@ static void new_cc_state(struct gsm_trans *trans, int state) static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STATUS"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); uint8_t *cause, *call_state; @@ -1320,7 +1320,7 @@ static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) static int gsm48_tx_simple(struct gsm_subscriber_connection *conn, uint8_t pdisc, uint8_t msg_type) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 TX SIMPLE"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); msg->lchan = conn->lchan; @@ -1943,7 +1943,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STUP"); struct gsm48_hdr *gh; struct gsm_mncc *setup = arg; int rc, trans_id; @@ -2067,7 +2067,7 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg) { struct gsm_mncc *proceeding = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROC"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_CALL_PROC; @@ -2129,7 +2129,7 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) { struct gsm_mncc *alerting = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC ALERT"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_ALERTING; @@ -2152,7 +2152,7 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) { struct gsm_mncc *progress = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROGRESS"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_PROGRESS; @@ -2169,7 +2169,7 @@ static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) { struct gsm_mncc *connect = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSN 04.08 CC CON"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_CONNECT; @@ -2258,7 +2258,7 @@ static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC CON ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_CONNECT_ACK; @@ -2324,7 +2324,7 @@ static struct gsm_mncc_cause default_cause = { static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg) { struct gsm_mncc *disc = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC DISC"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_DISCONNECT; @@ -2415,7 +2415,7 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) { struct gsm_mncc *rel = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_RELEASE; @@ -2505,7 +2505,7 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg) { struct gsm_mncc *rel = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL COMPL"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); int ret; @@ -2561,7 +2561,7 @@ static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg) { struct gsm_mncc *fac = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC FAC"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_FACILITY; @@ -2583,7 +2583,7 @@ static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_HOLD_ACK; @@ -2594,7 +2594,7 @@ static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg) { struct gsm_mncc *hold_rej = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD REJ"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_HOLD_REJ; @@ -2620,7 +2620,7 @@ static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_RETR_ACK; @@ -2631,7 +2631,7 @@ static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg) { struct gsm_mncc *retrieve_rej = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR REJ"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_RETR_REJ; @@ -2668,7 +2668,7 @@ static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg) { struct gsm_mncc *dtmf = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_START_DTMF_ACK; @@ -2683,7 +2683,7 @@ static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) { struct gsm_mncc *dtmf = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF REJ"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_START_DTMF_REJ; @@ -2699,7 +2699,7 @@ static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF STP ACK"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK; @@ -2743,7 +2743,7 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg) { struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_MODIFY; @@ -2786,7 +2786,7 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg) { struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD COMPL"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_MODIFY_COMPL; @@ -2833,7 +2833,7 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) { struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD REJ"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_MODIFY_REJECT; @@ -2851,7 +2851,7 @@ static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg) { struct gsm_mncc *notify = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC NOT"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_NOTIFY; @@ -2881,7 +2881,7 @@ static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg) { struct gsm_mncc *user = arg; - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USR INFO"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_USER_INFO; diff --git a/openbsc/src/libmsc/gsm_04_80.c b/openbsc/src/libmsc/gsm_04_80.c index b30f9ee..f1d75f2 100644 --- a/openbsc/src/libmsc/gsm_04_80.c +++ b/openbsc/src/libmsc/gsm_04_80.c @@ -65,7 +65,7 @@ int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn, const struct msgb *in_msg, const char *response_text, const struct ussd_request *req) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD RSP"); struct gsm48_hdr *gh; uint8_t *ptr8; int response_len; @@ -113,7 +113,7 @@ int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn, const struct msgb *in_msg, const struct ussd_request *req) { - struct msgb *msg = gsm48_msgb_alloc(); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD REJ"); struct gsm48_hdr *gh; /* First insert the problem code */ @@ -163,7 +163,7 @@ int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn) struct gsm48_hdr *gh; struct msgb *msg; - msg = gsm48_msgb_alloc(); + msg = gsm48_msgb_alloc_name("GSM 04.08 USSD REL COMPL"); if (!msg) return -1; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c index 2d2507e..a60940d 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c @@ -473,7 +473,7 @@ static int dtap_rcvmsg(struct osmo_bsc_sccp_con *conn, LOGP(DMSC, LOGL_INFO, "Rx MSC DTAP, SAPI: %u CHAN: %u\n", header->link_id & 0x07, header->link_id & 0xC0); /* forward the data */ - gsm48 = gsm48_msgb_alloc(); + gsm48 = gsm48_msgb_alloc_name("GSM 04.08 DTAP RCV"); if (!gsm48) { LOGP(DMSC, LOGL_ERROR, "Allocation of the message failed.\n"); return -1; -- 2.6.3 From laforge at gnumonks.org Mon Jan 25 20:17:04 2016 From: laforge at gnumonks.org (Harald Welte) Date: Mon, 25 Jan 2016 21:17:04 +0100 Subject: OsmoBTS and T200 handling / libosmocore lapdm Message-ID: <20160125201704.GY25837@nataraja> Hi all, T200 is the LAPDm re-transmission timer, after which the sender assumes a L2 frame transmitted was lost and starts with recovery. Until recently, OsmoBTS ignored the T200 values that the BSC specified via OML, always falling back to the (relatively long) T200 values that exist in libosmocore (1s for the main channel, 2s for the associated channel). As you know, OsmoBTS is used in production in this configuration and we never recevied any associated bug reports. Recently, in e9f12acbeb5a369282719f8e0deecc88034a5488 I started to use the T200 values as communicated from the BSC via OML. This is what proprietary BTSs like the BS-11, nanoBTS etc. (supposedly) have been using all the time anyway, so I thought of it as a bug fix. However, as it turns out, it breaks our LAPDm implementation in many ways. The LAPDm performance gets that bad that you cannot even transmit a single SMS anymore, and even LU only occasionally work anymore. You can see the erroneous behavior in the attached PCAP file showing OsmoBTS-generated GSMTAP and RSL. Also attached are log file outputs of LAPDm logging for mo-sms and mt-sms. In them you can find troubling lines like 'S frame response with F=1 error' which should never happen... I suspect two issues related to this: 1) Our lapdm.c code uses regular osmo_timer_* functions to determine once T200 expires, rather than a GSM frame number time-base. This wouldn't be a problem in a synchronous real-time environemnt. However, in OsmoBTS (as in OsmocomBB), there is a relatively long and queue / delay between the point where a frame is pulled out of the bottom end of LAPDm and actual transmission on the radio interface. However, LAPDm T200 starts ticking from the point the frame was pulled out, rather than from the point transmission started. In order to change this, I suggest that we either change LAPDm timers to work on frame numbers passed up from L1 via every L1SAP primitive (comparing RTS.ind for downlink vs. DATA.ind for uplink), or simply keeping a per-PHY/per-TRX measurement of that 'round trip time between the actual radio and the L2'. We can then compensate for this by adding it to T200. I briefly tried this here, where one given hardware indicated about 56ms round-trip-time (13 frames difference between RTS.ind and DATA.ind). However, it didn't help. Even compensating by 120ms was not sufficient. This needs to be revisited. 2) I think libosmogsm LAPDm implementation is actually buggy, specifically in situations where T200 expires. We don't see that often, as the 1s/2s is so long that in reality it rarely happens. Once the T200 value is reduced, the probability of running into T200 expiration increases, and so does the probability of seeing related problems. Our existing lapdm unit tests don't seem to cover timing related behavior, so that definitely is something tha appears to need improvement. Any help on those issues is appreciated. Meanwhile, I decided to revert back to the libosmogsm T200 defaults by the means of commit 3ca59512d2f4eb1f87699e8fada67f33674918b4 Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) -------------- next part -------------- A non-text attachment was scrubbed... Name: 20160125-osmobts-t200-gsmtap-rsl.pcap Type: application/vnd.tcpdump.pcap Size: 9597 bytes Desc: not available URL: -------------- next part -------------- <0010> lapd_core.c:2180 Message DL-DATA-REQUEST received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1756 writing message to send-queue: l3len: 2 <0010> lapd_core.c:1779 lapd_send_i() called from line 1762 <0010> lapd_core.c:1819 get message from send-queue <0010> lapd_core.c:1831 msg-len 2 sent 0 left 2 N201 20 length 2 first byte 05 <0010> lapd_core.c:1840 send I frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=1 V(A)=0) <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:545 Timeout T200 (0xb6a4a49c) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_TIMER_RECOV on SAPI(0) <0010> lapd_core.c:1542 incrementing V(R) to 1 <0010> lapd_core.c:1551 message in single I frame <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg DATA_IND from LAPDm to A-bis <0010> lapd_core.c:1779 lapd_send_i() called from line 1609 <0010> lapd_core.c:1789 timer recovery, not sending <0010> lapd_core.c:545 Timeout T200 (0xb6a4a49c) state=8 <0010> lapd_core.c:614 retransmit last frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:721 ack frame 0 <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1789 timer recovery, not sending <0010> lapd_core.c:545 Timeout T200 (0xb6a4a49c) state=8 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:545 Timeout T200 (0xb6a4a49c) state=8 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1281 RR response with F==1, and we are in timer recovery state, so we leave that state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1831 msg-len 2 sent 2 left 0 N201 20 length 0 first byte 05 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1232 S frame response with F=1 error <0010> lapd_core.c:378 sending MDL-ERROR-IND cause 6 <0010> lapdm.c:386 sending MDL-ERROR-IND 6 <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg ERROR_IND from LAPDm to A-bis <0010> lapd_core.c:1252 RR received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1232 S frame response with F=1 error <0010> lapd_core.c:378 sending MDL-ERROR-IND cause 6 <0010> lapdm.c:386 sending MDL-ERROR-IND 6 <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg ERROR_IND from LAPDm to A-bis <0010> lapd_core.c:1252 RR received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1232 S frame response with F=1 error <0010> lapd_core.c:378 sending MDL-ERROR-IND cause 6 <0010> lapdm.c:386 sending MDL-ERROR-IND 6 <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg ERROR_IND from LAPDm to A-bis <0010> lapd_core.c:1252 RR received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:789 SABM(E) received in state LAPD_STATE_IDLE <0010> lapd_core.c:227 new state LAPD_STATE_IDLE -> LAPD_STATE_MF_EST <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg EST_IND from LAPDm to A-bis <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_MF_EST on SAPI(3) <0010> lapd_core.c:1542 incrementing V(R) to 1 <0010> lapd_core.c:1560 message in multiple I frames (first message) <0010> lapd_core.c:1583 message in multiple I frames (next message) <0010> lapd_core.c:1779 lapd_send_i() called from line 1609 <0010> lapd_core.c:1618 we are not busy and have no pending data, send RR <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_MF_EST on SAPI(3) <0010> lapd_core.c:1542 incrementing V(R) to 2 <0010> lapd_core.c:1576 message in multiple I frames (last message) <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg DATA_IND from LAPDm to A-bis <0010> lapd_core.c:1779 lapd_send_i() called from line 1609 <0010> lapd_core.c:1618 we are not busy and have no pending data, send RR <0010> lapd_core.c:2180 Message DL-DATA-REQUEST received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1756 writing message to send-queue: l3len: 2 <0010> lapd_core.c:1779 lapd_send_i() called from line 1762 <0010> lapd_core.c:1819 get message from send-queue <0010> lapd_core.c:1831 msg-len 2 sent 0 left 2 N201 20 length 2 first byte 89 <0010> lapd_core.c:1840 send I frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=1 V(A)=0) <0010> lapd_core.c:2180 Message DL-DATA-REQUEST received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1756 writing message to send-queue: l3len: 5 <0010> lapd_core.c:1779 lapd_send_i() called from line 1762 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=1 V(A)=0) <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:992 UI received <0010> lapd_core.c:1019 length=0 (discarding) <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=8 <0010> lapd_core.c:614 retransmit last frame V(S)=0 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:721 ack frame 0 <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1789 timer recovery, not sending <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=8 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=8 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1281 RR response with F==1, and we are in timer recovery state, so we leave that state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1831 msg-len 2 sent 2 left 0 N201 20 length 0 first byte 89 <0010> lapd_core.c:1819 get message from send-queue <0010> lapd_core.c:1831 msg-len 5 sent 0 left 5 N201 20 length 5 first byte 89 <0010> lapd_core.c:1840 send I frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=2 V(A)=1) <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1281 RR response with F==1, and we are in timer recovery state, so we leave that state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1873 resend I frame from tx buffer V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=2 V(A)=1) <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1281 RR response with F==1, and we are in timer recovery state, so we leave that state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1873 resend I frame from tx buffer V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=2 V(A)=1) <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1252 RR received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1281 RR response with F==1, and we are in timer recovery state, so we leave that state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_MF_EST <0010> lapd_core.c:1779 lapd_send_i() called from line 1290 <0010> lapd_core.c:1873 resend I frame from tx buffer V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=2 V(A)=1) <0010> lapd_core.c:545 Timeout T200 (0xb6a4a590) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_TIMER_RECOV on SAPI(3) <0010> lapd_core.c:1542 incrementing V(R) to 3 <0010> lapd_core.c:721 ack frame 1 <0010> lapd_core.c:1551 message in single I frame <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg DATA_IND from LAPDm to A-bis <0010> lapd_core.c:1779 lapd_send_i() called from line 1609 <0010> lapd_core.c:1789 timer recovery, not sending <0010> lapd_core.c:2180 Message DL-RELEASE-REQUEST received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:2021 perform local release <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_IDLE <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg REL_CONF from LAPDm to A-bis <0010> lapd_core.c:2180 Message DL-DATA-REQUEST received in state LAPD_STATE_MF_EST <0010> lapd_core.c:1756 writing message to send-queue: l3len: 3 <0010> lapd_core.c:1779 lapd_send_i() called from line 1762 <0010> lapd_core.c:1819 get message from send-queue <0010> lapd_core.c:1831 msg-len 3 sent 0 left 3 N201 20 length 3 first byte 06 <0010> lapd_core.c:1840 send I frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapd_core.c:1802 k frames outstanding, not sending more (k=1 V(S)=2 V(A)=1) <0000> rsl.c:1822 (bts=0,trx=1,ts=0,ss=0) Rx RSL DEACTIVATE_SACCH <0006> oml.c:1432 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.req (SACCH TxDL) <0006> oml.c:1372 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.conf (SACCH TxDL) <0006> oml.c:1432 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.req (SACCH RxUL) <0006> oml.c:1372 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.conf (SACCH RxUL) <0006> oml.c:660 (bts=0,trx=1,ts=0,ss=0) End of queue encountered. Now empty? 1 <0010> lapd_core.c:545 Timeout T200 (0xb6a4a49c) state=7 <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:614 retransmit last frame V(S)=1 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1032 DISC received in state LAPD_STATE_TIMER_RECOV <0010> lapd_core.c:1076 DISC in est state <0010> lapd_core.c:212 stop T200 <0010> lapd_core.c:227 new state LAPD_STATE_TIMER_RECOV -> LAPD_STATE_IDLE <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg REL_IND from LAPDm to A-bis <0000> rsl.c:1822 (bts=0,trx=1,ts=0,ss=0) Rx RSL RF_CHAN_REL <0006> oml.c:1432 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.req (SDCCH RxUL) <0006> oml.c:1372 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.conf (SDCCH RxUL) <0006> oml.c:1432 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.req (SDCCH TxDL) <0006> oml.c:1372 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.conf (SDCCH TxDL) <0000> rsl.c:528 (bts=0,trx=1,ts=0,ss=0) Tx RF CHAN REL ACK <0006> oml.c:660 (bts=0,trx=1,ts=0,ss=0) End of queue encountered. Now empty? 1 -------------- next part -------------- <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:789 SABM(E) received in state LAPD_STATE_IDLE <0010> lapd_core.c:227 new state LAPD_STATE_IDLE -> LAPD_STATE_MF_EST <0010> lapd_core.c:896 Store content res. <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg EST_IND from LAPDm to A-bis <0010> lapdm.c:1137 ((nil)) RLL Message 'EST_REQ' received. (sapi 3) <0010> lapd_core.c:2180 Message DL-ESTABLISH-REQUEST received in state LAPD_STATE_IDLE <0010> lapd_core.c:1694 perform normal establishm. (SABM) <0010> lapd_core.c:227 new state LAPD_STATE_IDLE -> LAPD_STATE_SABM_SENT <0010> lapd_core.c:196 start T200 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:789 SABM(E) received in state LAPD_STATE_MF_EST <0010> lapd_core.c:815 SABM command, multiple frame established state <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_MF_EST on SAPI(0) <0010> lapd_core.c:1542 incrementing V(R) to 1 <0010> lapd_core.c:1551 message in single I frame <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg DATA_IND from LAPDm to A-bis <0010> lapd_core.c:1779 lapd_send_i() called from line 1609 <0010> lapd_core.c:1618 we are not busy and have no pending data, send RR <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0010> lapd_core.c:196 start T200 <0005> paging.c:512 Removed paging record, queue_len=0 <0010> lapdm.c:550 fmt=B <0010> lapd_core.c:992 UI received <0000> rsl.c:1734 (bts=0,trx=1,ts=0,ss=0) Handing RLL msg UNIT_DATA_IND from LAPDm to MEAS REP <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_MF_EST on SAPI(0) <0010> lapd_core.c:1508 N(S) sequence error: N(S)=0, V(R)=1 <0010> lapd_core.c:1779 lapd_send_i() called from line 1534 <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0010> lapd_core.c:196 start T200 <0010> lapdm.c:561 fmt=B <0010> lapd_core.c:1459 I received in state LAPD_STATE_MF_EST on SAPI(0) <0010> lapd_core.c:1508 N(S) sequence error: N(S)=0, V(R)=1 <0010> lapd_core.c:1779 lapd_send_i() called from line 1534 <0010> lapd_core.c:545 Timeout T200 (0xb6a26590) state=5 <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg REL_IND from LAPDm to A-bis <0010> lapd_core.c:378 sending MDL-ERROR-IND cause 1 <0010> lapdm.c:386 sending MDL-ERROR-IND 1 <0000> rsl.c:1741 (bts=0,trx=1,ts=0,ss=0) Fwd RLL msg ERROR_IND from LAPDm to A-bis <0010> lapd_core.c:227 new state LAPD_STATE_SABM_SENT -> LAPD_STATE_IDLE <0000> rsl.c:1822 (bts=0,trx=1,ts=0,ss=0) Rx RSL DEACTIVATE_SACCH <0006> oml.c:1432 (bts=0,trx=1,ts=0,ss=0) MPH-DEACTIVATE.req (SACCH TxDL) <0010> lapd_core.c:2180 Message DL-RELEASE-REQUEST received in state LAPD_STATE_MF_EST <0010> lapd_core.c:2021 perform local release <0010> lapd_core.c:227 new state LAPD_STATE_MF_EST -> LAPD_STATE_IDLE From alexander.huemer at xx.vu Mon Jan 25 22:49:53 2016 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Mon, 25 Jan 2016 23:49:53 +0100 Subject: OAP depends on libgtp? (openbsc:6cacc56d) In-Reply-To: <20160118100935.GA1392@dub6> References: <20160118100935.GA1392@dub6> Message-ID: <20160125224953.GA26211@yade.xx.vu> Hi! On Mon, Jan 18, 2016 at 11:09:35AM +0100, Neels Hofmeyr wrote: > about your commit on openbsc, merged as 6cacc56d: libgtp should not be a > prerequisite for OAP. OAP is a rather simple protocol built on an IPA > connection and doesn't really relate to GTP at all. > > So if your build of OAP was dependent on libgtp, that's a bug, and > probably my fault. > > Could you please verify / indicate the failure you saw so we/I can fix > it? I just revisited the situation. The tests in tests/oap are either way only built when both LIBCARES and LIBGTP are present because of the clause in tests/Makefile.am. At this point I cannot reconstruct how exactly I came up with this patch. I think that conditional in tests/Makefile.am is there because of the similar conditional in src/gprs. osmo-sgsn only gets built when those two libraries are present. src/gprs/oap.o is a dependency of only osmo-sgsn. When the tests in tests/oap are built unconditionally, but osmo-sgsn wasn't built before because of a missing dependency, that fails with: make[3]: Entering directory '/home/blackbit/src/telco/osmo/openbsc/openbsc/tests/oap' CC ../../src/gprs/oap.o ../../src/gprs/oap.c:256:1: fatal error: opening dependency file .deps/../../src/gprs/oap.Tpo: No such file or directory } ^ compilation terminated. Makefile:375: recipe for target '../../src/gprs/oap.o' failed make[3]: *** [../../src/gprs/oap.o] Error 1 oap.o isn't built in this case if it is needed, it is pulled in with LDADD. So, whether oap is built currently is indirectly dependent on the presence of LIBCARES and LIBGTP, but the patch would not have been needed, because of the conditional in tests/Makefile.am. It's all a bit ocnfusing :-) Interestingly, while digging around I found a different minor issue in the buildsystem that is only visible when the dependencies are installed in distinct directories. It's surprising that I didn't stumble upon that initially. I'll send a seperate patch for that. Kind regards, -Alex -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: From alexander.huemer at xx.vu Mon Jan 25 23:50:34 2016 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Tue, 26 Jan 2016 00:50:34 +0100 Subject: A patch for openbsc Message-ID: <1453765835-23044-1-git-send-email-alexander.huemer@xx.vu> Hi, without this patch the needed files of libgtp are only found if they are placed in the same location as other dependencies. When GNU stow is used this may not be the case. Kind regards, -Alex From alexander.huemer at xx.vu Mon Jan 25 23:50:35 2016 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Tue, 26 Jan 2016 00:50:35 +0100 Subject: [PATCH] gprs: use libgtp cflags In-Reply-To: <1453765835-23044-1-git-send-email-alexander.huemer@xx.vu> References: <1453765835-23044-1-git-send-email-alexander.huemer@xx.vu> Message-ID: <1453765835-23044-2-git-send-email-alexander.huemer@xx.vu> --- openbsc/src/gprs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 295fb86..f406dd7 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -2,7 +2,7 @@ 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) + $(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) -- 2.7.0.rc3 From ralph at schmid.xxx Tue Jan 26 09:41:11 2016 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 26 Jan 2016 10:41:11 +0100 Subject: GSM demo licenses in Germany? Message-ID: <068001d1581d$b1c09820$1541c860$@schmid.xxx> Hi, As there are some German GSM experimenters here, what happened to your demo licenses after the DECT guard band frequencies had been auctioned away to AFAIR Vodafone? What a stupid idea, they did not listen to the technicians and just had the $$$ signs in their eyes :( I got a reminder last week, my license would expire soon, and if I would like to renew it. So I answered intentionally unknowingly "yes, please do so". Let's see what they will do now :) The second possibility would be asking the management of a German provider if they would lend me one of their unused guard channels. Although I see there chances I really would hate pulling this wire... Ralph. From suraev at alumni.ntnu.no Tue Jan 26 09:50:04 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Tue, 26 Jan 2016 10:50:04 +0100 Subject: [PATCH 3/5] Add bitvector functions from osmo-pcu In-Reply-To: <56A64CCD.8090403@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-3-git-send-email-suraev@alumni.ntnu.no> <656A0B94-6056-49AD-A8A3-74434E5195C4@freyther.de> <56A614F4.3000903@alumni.ntnu.no> <68858672-9913-4510-A275-245C4891485F@freyther.de> <56A64CCD.8090403@alumni.ntnu.no> Message-ID: <56A7414C.3060109@alumni.ntnu.no> v3 attached with style corrections. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Add-bitvec-related-functions-from-Osmo-PCU.patch Type: text/x-patch Size: 4303 bytes Desc: not available URL: From nhofmeyr at sysmocom.de Tue Jan 26 10:12:20 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Tue, 26 Jan 2016 11:12:20 +0100 Subject: OAP depends on libgtp? (openbsc:6cacc56d) In-Reply-To: <20160125224953.GA26211@yade.xx.vu> References: <20160118100935.GA1392@dub6> <20160125224953.GA26211@yade.xx.vu> Message-ID: <20160126101220.GA1702@dub6> Hey Alexander, many thanks for your investigation! I think the root cause of this is that oap.c should not live in gprs. It is in there because it's so thin and we (probably) figured it wouldn't be worth the effort putting it elsewhere. So after all, it *would* have been worth the effort, because we wouldn't have to wonder about it today ;) I'll have another look and see whether I can easily pull OAP into a separate, tiny static lib, or otherwise I'll just add a comment at those "if HAVE_" places. > So, whether oap is built currently is indirectly dependent on the > presence of LIBCARES and LIBGTP, but the patch would not have been > needed, because of the conditional in tests/Makefile.am. Maybe the patch fixes an error if one runs 'make' in tests/oap directly? Or a missing autoreconf after pulling? ... something like that probably. > It's all a bit ocnfusing :-) quite soncufing, agreed ;) Thanks again! ~Neels On Mon, Jan 25, 2016 at 11:49:53PM +0100, Alexander Huemer wrote: > Hi! > > On Mon, Jan 18, 2016 at 11:09:35AM +0100, Neels Hofmeyr wrote: > > about your commit on openbsc, merged as 6cacc56d: libgtp should not be a > > prerequisite for OAP. OAP is a rather simple protocol built on an IPA > > connection and doesn't really relate to GTP at all. > > > > So if your build of OAP was dependent on libgtp, that's a bug, and > > probably my fault. > > > > Could you please verify / indicate the failure you saw so we/I can fix > > it? > > I just revisited the situation. > The tests in tests/oap are either way only built when both LIBCARES and > LIBGTP are present because of the clause in tests/Makefile.am. > At this point I cannot reconstruct how exactly I came up with this > patch. > I think that conditional in tests/Makefile.am is there because of the > similar conditional in src/gprs. > osmo-sgsn only gets built when those two libraries are present. > src/gprs/oap.o is a dependency of only osmo-sgsn. > When the tests in tests/oap are built unconditionally, but osmo-sgsn > wasn't built before because of a missing dependency, that fails with: > > > make[3]: Entering directory '/home/blackbit/src/telco/osmo/openbsc/openbsc/tests/oap' > CC ../../src/gprs/oap.o > ../../src/gprs/oap.c:256:1: fatal error: opening dependency file .deps/../../src/gprs/oap.Tpo: No such file or directory > } > ^ > compilation terminated. > Makefile:375: recipe for target '../../src/gprs/oap.o' failed > make[3]: *** [../../src/gprs/oap.o] Error 1 > > oap.o isn't built in this case if it is needed, it is pulled in with > LDADD. > > > > Interestingly, while digging around I found a different minor issue in > the buildsystem that is only visible when the dependencies are installed > in distinct directories. It's surprising that I didn't stumble upon that > initially. I'll send a seperate patch for that. > > Kind regards, > -Alex -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Tue Jan 26 10:12:30 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 26 Jan 2016 11:12:30 +0100 Subject: [PATCH 2/2] Get rid of duplicated timer code In-Reply-To: <1453737688-27611-2-git-send-email-suraev@alumni.ntnu.no> References: <1453737688-27611-1-git-send-email-suraev@alumni.ntnu.no> <1453737688-27611-2-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 25 Jan 2016, at 17:01, suraev at alumni.ntnu.no wrote: > > while (!quit) { > - osmo_gsm_timers_check(); > - osmo_gsm_timers_prepare(); > - osmo_gsm_timers_update(); > + osmo_timers_check(); > + osmo_timers_prepare(); > + osmo_timers_update(); > > osmo_select_main(0); timers_check,_prepare and _update are called from osmo_select_main already so they are not needed. The general idea to work in frame numbers makes a lot of sense, the question is why we are not working with it anymore. a.) Our fn's are not monotonic and we can work in time then we do not need this code b.) We should do things based on the fn (e.g. the T200 issues we found in LAPDm show that it can be a good idea). holger From holger at freyther.de Tue Jan 26 10:22:09 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 26 Jan 2016 11:22:09 +0100 Subject: [PATCH 4/5] Expand bitvec interface In-Reply-To: <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> Message-ID: <28DA569B-B039-4896-9DDF-ACBF8DA124E8@freyther.de> > On 22 Jan 2016, at 16:46, suraev at alumni.ntnu.no wrote: > > > + * (C) 2015 by Sysmocom s.f.m.c. GmbH, Author: Max not too fair for the previous contributor? So Authors if we want to have it? I let Harald comment on the right way to list authors in case they want to be mentioned. > > +/*! \brief get multiple bits (num_bits) from beginning of vector (MSB side) */ > +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits) > +{ > + if (num_bits > 15 || bv->cur_bit < num_bits) return -EINVAL; coding style. Add newline here as well for the return > + > + if (num_bits < 9) { > + return bv->data[0] >> (8 - num_bits); > + } no braces, > + > + uint8_t tmp[2]; variable definitions not on first use but at the beginning of the scope. :} > + > /*! \brief get multiple bits (based on numeric value) from current pos */ > int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) > { > @@ -243,17 +260,26 @@ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) > return ui; > } > > -/*! \brief pad all remaining bits up to num_bits */ > -int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) > +/*! \brief fill num_bits with \fill starting from the current position > + * returns 0 on success, negative otherwise (out of vector boundary) > + */ > +int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill) > { > - unsigned int i; > - > - for (i = bv->cur_bit; i <= up_to_bit; i++) > - bitvec_set_bit(bv, L); > + unsigned i, stop = bv->cur_bit + num_bits; > + for (i = bv->cur_bit; i < stop; i++) > + if (bitvec_set_bit(bv, fill) < 0) return -EINVAL; coding style, add newline and indent for the return statement. > > return 0; > } > > +/*! \brief pad all remaining bits up to num_bits */ > +int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) > +{ > + int n = up_to_bit - bv->cur_bit + 1; > + if (n < 1) return 0; coding style. > + return bitvec_fill(bv, n, L); > +} > + > /*! \brief find first bit set in bit vector */ > int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, > enum bit_value val) > @@ -428,4 +454,94 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val > return 0; > } > > +/*! \brief convert enum to corresponding character */ > +char bit_value_to_char(enum bit_value v) > +{ > + switch (v) { > + case ZERO: return '0'; > + case ONE: return '1'; > + case L: return 'L'; > + case H: return 'H'; newline for the return? > + } > + return 'X'; // make compiler happy is it complaining? use default: and __builtin_not_reached or such? > +} > + > +/*! \brief prints bit vector to provided string > + * It's caller's responcibility to ensure that we won't shoot him in the foot. > + */ > +void bitvec_to_string_r(const struct bitvec *bv, char *str) > +{ > + unsigned i, pos = 0; > + char *cur = str; > + for (i = 0; i < bv->cur_bit; i++) { > + if (0 == i % 8) *cur++ = ' '; coding style and add line wrapping > + *cur++ = bit_value_to_char(bitvec_get_bit_pos(bv, i)); > + pos++; > + } > + *cur = 0; > +} > + > +/* we assume that x have at least 1 non-b bit */ > +static inline unsigned _leading_bits(uint8_t x, bool b) > +{ > + if (b) { > + if (x < 0x80) return 0; > + if (x < 0xC0) return 1; > + if (x < 0xE0) return 2; > + if (x < 0xF0) return 3; > + if (x < 0xF8) return 4; > + if (x < 0xFC) return 5; > + if (x < 0xFE) return 6; > + } else { > + if (x > 0x7F) return 0; > + if (x > 0x3F) return 1; > + if (x > 0x1F) return 2; > + if (x > 0xF) return 3; > + if (x > 7) return 4; > + if (x > 3) return 5; > + if (x > 1) return 6; > + } same coding style thing > + return 7; > +} > +/*! \brief force bit vector to all 0 and current bit to the beginnig of the vector */ > +void bitvec_zero(struct bitvec *bv) > +{ > + bv->cur_bit = 0; > + memset(bv->data, 0, bv->data_len); > +} > + > +/*! \brief Return number (bits) of uninterrupted run of \b in \bv starting from the MSB */ > +unsigned bitvec_rl(const struct bitvec *bv, bool b) > +{ > + unsigned i; > + for (i = 0; i < (bv->cur_bit % 8 ? bv->cur_bit / 8 + 1 : bv->cur_bit / 8); i++) { > + if ( (b ? 0xFF : 0) != bv->data[i]) return i * 8 + _leading_bits(bv->data[i], b); coding style add new line > + } > + > + return bv->cur_bit; > +} > + > +/*! \brief Shifts bitvec to the left, n MSB bits lost */ > +void bitvec_shiftl(struct bitvec *bv, unsigned n) > +{ > + if (0 == n) return; coding style > + if (n >= bv->cur_bit) { > + bitvec_zero(bv); > + return; > + } > + > + memmove(bv->data, bv->data + n / 8, bv->data_len - n / 8); > + > + uint8_t tmp[2]; > + unsigned i; > + for (i = 0; i < bv->data_len - 2; i++) { > + uint16_t t = osmo_load16be(bv->data + i); > + osmo_store16be(t << (n % 8), &tmp); > + bv->data[i] = tmp[0]; > + } > + > + bv->data[bv->data_len - 1] <<= (n % 8); > + bv->cur_bit -= n; otherwise it does look fine. holger From jerlbeck at sysmocom.de Tue Jan 26 11:17:46 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 26 Jan 2016 12:17:46 +0100 Subject: [PATCH 4/5] Expand bitvec interface In-Reply-To: <28DA569B-B039-4896-9DDF-ACBF8DA124E8@freyther.de> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> <28DA569B-B039-4896-9DDF-ACBF8DA124E8@freyther.de> Message-ID: <56A755DA.1010603@sysmocom.de> On 26.01.2016 11:22, Holger Freyther wrote: > >> On 22 Jan 2016, at 16:46, suraev at alumni.ntnu.no wrote: >> +/* we assume that x have at least 1 non-b bit */ >> +static inline unsigned _leading_bits(uint8_t x, bool b) >> +{ >> + if (b) { >> + if (x < 0x80) return 0; >> + if (x < 0xC0) return 1; >> + if (x < 0xE0) return 2; >> + if (x < 0xF0) return 3; >> + if (x < 0xF8) return 4; >> + if (x < 0xFC) return 5; >> + if (x < 0xFE) return 6; >> + } else { >> + if (x > 0x7F) return 0; >> + if (x > 0x3F) return 1; >> + if (x > 0x1F) return 2; >> + if (x > 0xF) return 3; >> + if (x > 7) return 4; >> + if (x > 3) return 5; >> + if (x > 1) return 6; >> + } > > same coding style thing In such cases, the readability would suffer when putting the returns in the next line. I'd rather right align the numbers after the '>', but YMMV. Jacob -- - Jacob Erlbeck http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From ralph at schmid.xxx Tue Jan 26 11:51:16 2016 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 26 Jan 2016 12:51:16 +0100 Subject: Hardware question Message-ID: <07a501d1582f$dde27c90$99a775b0$@schmid.xxx> Hi, My intention is setting up a small dedicated box with a PC and some RF hardware for GSM1800. The usage will be mainly SMS and EDGE. Is it still recommended using something like a nanoBTS, with the nitb setup? These are relative cheap, professionally designed. UmTRX looks great, but it is above the financial limit. It will be an experimental setup, but more for demonstrational purpose, so I love the idea of some nice looking plug and play box. It is not intended to extend it, no hand over, no roaming stuff, no interconnection other than IP and maybe SIP. For testing still I have my B210 and a BladeRF, but I do not want to waste such a versatile SDR for some stupid test BTS stuff :) Thanks for any input! Ralph. -- Ralph A. Schmid Mondstr. 10 90762 F?rth +49-171-3631223 ralph at schmid.xxx http://www.bclog.de/ From jerlbeck at sysmocom.de Tue Jan 26 12:31:29 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 26 Jan 2016 13:31:29 +0100 Subject: Hardware question In-Reply-To: <07a501d1582f$dde27c90$99a775b0$@schmid.xxx> References: <07a501d1582f$dde27c90$99a775b0$@schmid.xxx> Message-ID: <56A76721.6080209@sysmocom.de> Hi, On 26.01.2016 12:51, Ralph A. Schmid, dk5ras wrote: > My intention is setting up a small dedicated box with a PC and some RF > hardware for GSM1800. The usage will be mainly SMS and EDGE. Which EDGE specific (in comparison to GPRS) features do you need? Jacob -- - Jacob Erlbeck http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From holger at freyther.de Tue Jan 26 13:32:31 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 26 Jan 2016 14:32:31 +0100 Subject: [PATCH 4/5] Expand bitvec interface In-Reply-To: <56A755DA.1010603@sysmocom.de> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> <28DA569B-B039-4896-9DDF-ACBF8DA124E8@freyther.de> <56A755DA.1010603@sysmocom.de> Message-ID: <160912F4-8E05-468D-B098-55210AB549A3@freyther.de> > On 26 Jan 2016, at 12:17, Jacob Erlbeck wrote: > > On 26.01.2016 11:22, Holger Freyther wrote: >> >>> On 22 Jan 2016, at 16:46, suraev at alumni.ntnu.no wrote: > >>> +/* we assume that x have at least 1 non-b bit */ >>> +static inline unsigned _leading_bits(uint8_t x, bool b) >>> +{ >>> + if (b) { >>> + if (x < 0x80) return 0; >>> + if (x < 0xC0) return 1; >>> + if (x < 0xE0) return 2; >>> + if (x < 0xF0) return 3; >>> + if (x < 0xF8) return 4; >>> + if (x < 0xFC) return 5; >>> + if (x < 0xFE) return 6; >>> + } else { >>> + if (x > 0x7F) return 0; >>> + if (x > 0x3F) return 1; >>> + if (x > 0x1F) return 2; >>> + if (x > 0xF) return 3; >>> + if (x > 7) return 4; >>> + if (x > 3) return 5; >>> + if (x > 1) return 6; >>> + } >> >> same coding style thing > > In such cases, the readability would suffer when putting the returns in > the next line. I'd rather right align the numbers after the '>', but YMMV. sure or somemthing like case 0xff..0x80: return 0; case 0x7F..0xC0: return 1; anyway, the above is okay and something we can argue with but if it is more than a "look-up table" then we should break the line. From ralph at schmid.xxx Tue Jan 26 13:32:33 2016 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 26 Jan 2016 14:32:33 +0100 Subject: Hardware question In-Reply-To: <56A76721.6080209@sysmocom.de> References: <07a501d1582f$dde27c90$99a775b0$@schmid.xxx> <56A76721.6080209@sysmocom.de> Message-ID: <06ca01d1583e$03c4f0b0$0b4ed210$@schmid.xxx> Hi, > Which EDGE specific (in comparison to GPRS) features do you need? No specific features, EDGE just would be nice by means of throughput and latency. I do not intend to set up strange combinations. In case EDGE is not possible, GPRS will do just fine for demo purposes, too. I have such a demo box already, but it is some prototype, development on it has stopped a time ago, so it is kind of "static". The demo box should not be updated with all untested features all the time, but no updates at all are a bit lame :-) Also its 19" form factor is not very portable, and the transceiver board is somehow bulky, too. I would have built it into a nice housing if it had a future, but it is a dead end now. > Jacob Ralph. From sipos.csaba at kvk.uni-obuda.hu Tue Jan 26 13:41:24 2016 From: sipos.csaba at kvk.uni-obuda.hu (Sipos Csaba) Date: Tue, 26 Jan 2016 14:41:24 +0100 (CET) Subject: Hardware question In-Reply-To: <06ca01d1583e$03c4f0b0$0b4ed210$@schmid.xxx> References: <07a501d1582f$dde27c90$99a775b0$@schmid.xxx> <56A76721.6080209@sysmocom.de> <06ca01d1583e$03c4f0b0$0b4ed210$@schmid.xxx> Message-ID: <528576027.19750502.1453815684698.JavaMail.zimbra@kvk.uni-obuda.hu> Hi Ralph, What we do at the university is just using the upper ARFCNs (882-885), because the 20MHz LTE the owner of this part of the band use is allowing almost 0.8MHz "free" spectrum. THe guard band is designed for high power transmitters, for testing we are using 100-200mW Tx power, so we are very far from bleeding into the actual used portion of the operator, so we are not creating any interference, and we always check the availability of the spectrum with analysis. I think the key for short term low power proejcts is to always check for available spectrum, never create any interference, and newer try to mimic a commercial operator by using their MCCMNC code and/or the operator name, and if your network is out in the air, always make it a closed one and make sure the commercial users will be properly reject (with PLMN not allowed reject cause). Of corse this is not a legal advice, but we are doing so for years now, and nobody ever complained :-) If you check carefully, the law is actually not prohibiting the use of licensed portion of the spectrum (eg. interfering), but punishes the possible conseqences (loss of revenue, disturbing a public telephony service, someone dies because of your interference he/she cannot call the ambulance etc.). Until you do not meet any of those circumstances, you will be fine. Regards, Csaba ----- Eredeti ?zenet ----- Felad?: "Ralph A. Schmid, dk5ras" C?mzett: "Jacob Erlbeck" , openbsc at lists.osmocom.org Elk?ld?tt ?zenetek: Kedd, 2016. Janu?r 26. 14:32:33 T?rgy: RE: Hardware question Hi, > Which EDGE specific (in comparison to GPRS) features do you need? No specific features, EDGE just would be nice by means of throughput and latency. I do not intend to set up strange combinations. In case EDGE is not possible, GPRS will do just fine for demo purposes, too. I have such a demo box already, but it is some prototype, development on it has stopped a time ago, so it is kind of "static". The demo box should not be updated with all untested features all the time, but no updates at all are a bit lame :-) Also its 19" form factor is not very portable, and the transceiver board is somehow bulky, too. I would have built it into a nice housing if it had a future, but it is a dead end now. > Jacob Ralph. From nhofmeyr at sysmocom.de Tue Jan 26 14:01:45 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Tue, 26 Jan 2016 15:01:45 +0100 Subject: const question Message-ID: <20160126140145.GA10261@dub6> Hi, my attention was directed at the gprs_shift_v_fixed() function: int gprs_shift_v_fixed(uint8_t **data, size_t *data_len, size_t len, uint8_t **value) It advances the *data pointer and returns a *value pointer. So it could technically be consting much more aggressively. However, the compiler warnings confuse me. I've created this test code to illustrate; the ints should be treated read-only by func(): void func(const int **yyy) { (*yyy) ++; } int main(void) { int y[2] = {23, 42}; // mutable "by coincidence" int *yy = y; func(&yy); return *yy; // returns 42 } The idea is that yy is a pointer to a mutable int. func() expects a const int, but what harm could be done by passing a mutable-int pointer as an immutable-int pointer. Apparently this harm: check.c: In function ?main?: check.c:10:14: warning: passing argument 1 of ?func? from incompatible pointer type func(&yy); ^ check.c:1:6: note: expected ?const int **? but argument is of type ?int **? void func(const int **yyy) Changing yy to a pointer-to-const-int clears the warning: const int *yy = y; func(&yy); I'm expecting the const to apply to the int pointed at, so I should be able to modify the pointer while the compiler shouldn't waste a thought at whether the int pointed at is const or not. func() is stricter, not less strict than y[]. To further illustrate, this would make the pointer address itself immutable, which is not what I want: int * const yy = y; I just want to declare the underlying int data to be unchangeable by func(), not caring whether the caller passes a const int or a mutable int buffer. Is the compiler merely nitpicking or am I getting something wrong fundamentally? Thanks! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From suraev at alumni.ntnu.no Tue Jan 26 15:22:23 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 16:22:23 +0100 Subject: [PATCH 1/2] Cleanup build Message-ID: <1453821744-16428-1-git-send-email-suraev@alumni.ntnu.no> From: Max Ignore cross-compilation bild byproducts. Enable subdir-objects to increase compatibility with newer automake. --- .gitignore | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6cc9aa5..439f591 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ depcomp install-sh missing libtool +arm*linux*libtool +compile ltmain.sh core diff --git a/configure.ac b/configure.ac index 5274022..7a97954 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_INIT([osmo-pcu], m4_esyscmd([./git-version-gen .tarball-version]), [osmocom-net-gprs at lists.osmocom.org]) -AM_INIT_AUTOMAKE([dist-bzip2]) +AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects]) AC_CONFIG_TESTDIR(tests) dnl kernel style compile messages -- 2.5.0 From suraev at alumni.ntnu.no Tue Jan 26 15:22:24 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 16:22:24 +0100 Subject: [PATCH 2/2] Restructure sources In-Reply-To: <1453821744-16428-1-git-send-email-suraev@alumni.ntnu.no> References: <1453821744-16428-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453821744-16428-2-git-send-email-suraev@alumni.ntnu.no> From: Max Move hardware-spicefic files into subdirectory similar to the way it's done in OsmoBTS to make adding more hardware support easier. Make DSP access option name generic. --- src/Makefile.am | 51 +++-- src/femtobts.c | 275 -------------------------- src/femtobts.h | 57 ------ src/osmo-bts-sysmo/femtobts.c | 275 ++++++++++++++++++++++++++ src/osmo-bts-sysmo/femtobts.h | 57 ++++++ src/osmo-bts-sysmo/sysmo_l1_fwd.c | 145 ++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_hw.c | 216 +++++++++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_if.c | 396 ++++++++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_if.h | 91 +++++++++ src/osmobts_sock.cpp | 2 +- src/pcu_l1_if.cpp | 6 +- src/sysmo_l1_fwd.c | 145 -------------- src/sysmo_l1_hw.c | 216 --------------------- src/sysmo_l1_if.c | 396 -------------------------------------- src/sysmo_l1_if.h | 91 --------- 15 files changed, 1214 insertions(+), 1205 deletions(-) delete mode 100644 src/femtobts.c delete mode 100644 src/femtobts.h create mode 100644 src/osmo-bts-sysmo/femtobts.c create mode 100644 src/osmo-bts-sysmo/femtobts.h create mode 100644 src/osmo-bts-sysmo/sysmo_l1_fwd.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_hw.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_if.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_if.h delete mode 100644 src/sysmo_l1_fwd.c delete mode 100644 src/sysmo_l1_hw.c delete mode 100644 src/sysmo_l1_if.c delete mode 100644 src/sysmo_l1_if.h diff --git a/src/Makefile.am b/src/Makefile.am index 6428bef..3049744 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) if ENABLE_SYSMODSP -AM_CPPFLAGS += -DENABLE_SYSMODSP +AM_CPPFLAGS += -DENABLE_DIRECT_PHY endif AM_CXXFLAGS = -Wall -ldl -pthread @@ -64,11 +64,6 @@ bin_PROGRAMS = \ noinst_PROGRAMS = -if ENABLE_SYSMODSP -noinst_PROGRAMS += \ - osmo-pcu-remote -endif - noinst_HEADERS = \ gprs_debug.h \ csn1.h \ @@ -83,8 +78,6 @@ noinst_HEADERS = \ bitvector.h \ pcu_vty.h \ pcu_vty_functions.h \ - sysmo_l1_if.h \ - femtobts.h \ tbf.h \ bts.h \ poll_controller.h \ @@ -101,30 +94,46 @@ noinst_HEADERS = \ osmo_pcu_SOURCES = pcu_main.cpp if ENABLE_SYSMODSP -osmo_pcu_SOURCES += sysmo_l1_if.c \ - sysmo_l1_hw.c \ - femtobts.c - -osmo_pcu_remote_SOURCES = pcu_main.cpp \ - sysmo_l1_if.c \ - sysmo_l1_fwd.c \ - femtobts.c -endif +AM_CPPFLAGS += -I$(srcdir)/osmo-bts-sysmo -osmo_pcu_LDADD = \ +EXTRA_DIST = \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c \ + osmo-bts-sysmo/femtobts.h + +noinst_HEADERS += \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/femtobts.h + +noinst_PROGRAMS += \ + osmo-pcu-remote + +osmo_pcu_SOURCES += \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_SOURCES = \ + pcu_main.cpp \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_fwd.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) +endif -if ENABLE_SYSMODSP -osmo_pcu_remote_LDADD = \ +osmo_pcu_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) -endif #MOSTLYCLEANFILES += testSource testDestination diff --git a/src/femtobts.c b/src/femtobts.c deleted file mode 100644 index f6957d2..0000000 --- a/src/femtobts.c +++ /dev/null @@ -1,275 +0,0 @@ -/* sysmocom femtobts L1 API related definitions */ - -/* (C) 2011 by Harald Welte - * - * 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 "femtobts.h" - -const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM] = { - [GsmL1_PrimId_MphInitReq] = L1P_T_REQ, - [GsmL1_PrimId_MphCloseReq] = L1P_T_REQ, - [GsmL1_PrimId_MphConnectReq] = L1P_T_REQ, - [GsmL1_PrimId_MphDisconnectReq] = L1P_T_REQ, - [GsmL1_PrimId_MphActivateReq] = L1P_T_REQ, - [GsmL1_PrimId_MphDeactivateReq] = L1P_T_REQ, - [GsmL1_PrimId_MphConfigReq] = L1P_T_REQ, - [GsmL1_PrimId_MphMeasureReq] = L1P_T_REQ, - [GsmL1_PrimId_MphInitCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphCloseCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphConnectCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphDisconnectCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphActivateCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphDeactivateCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphConfigCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphMeasureCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphTimeInd] = L1P_T_IND, - [GsmL1_PrimId_MphSyncInd] = L1P_T_IND, - [GsmL1_PrimId_PhEmptyFrameReq] = L1P_T_REQ, - [GsmL1_PrimId_PhDataReq] = L1P_T_REQ, - [GsmL1_PrimId_PhConnectInd] = L1P_T_IND, - [GsmL1_PrimId_PhReadyToSendInd] = L1P_T_IND, - [GsmL1_PrimId_PhDataInd] = L1P_T_IND, - [GsmL1_PrimId_PhRaInd] = L1P_T_IND, -}; - -const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1] = { - { GsmL1_PrimId_MphInitReq, "MPH-INIT.req" }, - { GsmL1_PrimId_MphCloseReq, "MPH-CLOSE.req" }, - { GsmL1_PrimId_MphConnectReq, "MPH-CONNECT.req" }, - { GsmL1_PrimId_MphDisconnectReq,"MPH-DISCONNECT.req" }, - { GsmL1_PrimId_MphActivateReq, "MPH-ACTIVATE.req" }, - { GsmL1_PrimId_MphDeactivateReq,"MPH-DEACTIVATE.req" }, - { GsmL1_PrimId_MphConfigReq, "MPH-CONFIG.req" }, - { GsmL1_PrimId_MphMeasureReq, "MPH-MEASURE.req" }, - { GsmL1_PrimId_MphInitCnf, "MPH-INIT.conf" }, - { GsmL1_PrimId_MphCloseCnf, "MPH-CLOSE.conf" }, - { GsmL1_PrimId_MphConnectCnf, "MPH-CONNECT.conf" }, - { GsmL1_PrimId_MphDisconnectCnf,"MPH-DISCONNECT.conf" }, - { GsmL1_PrimId_MphActivateCnf, "MPH-ACTIVATE.conf" }, - { GsmL1_PrimId_MphDeactivateCnf,"MPH-DEACTIVATE.conf" }, - { GsmL1_PrimId_MphConfigCnf, "MPH-CONFIG.conf" }, - { GsmL1_PrimId_MphMeasureCnf, "MPH-MEASURE.conf" }, - { GsmL1_PrimId_MphTimeInd, "MPH-TIME.ind" }, - { GsmL1_PrimId_MphSyncInd, "MPH-SYNC.ind" }, - { GsmL1_PrimId_PhEmptyFrameReq, "PH-EMPTY_FRAME.req" }, - { GsmL1_PrimId_PhDataReq, "PH-DATA.req" }, - { GsmL1_PrimId_PhConnectInd, "PH-CONNECT.ind" }, - { GsmL1_PrimId_PhReadyToSendInd,"PH-READY_TO_SEND.ind" }, - { GsmL1_PrimId_PhDataInd, "PH-DATA.ind" }, - { GsmL1_PrimId_PhRaInd, "PH-RA.ind" }, - { 0, NULL } -}; - -const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM] = { - [GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf, - [GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf, - [GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf, - [GsmL1_PrimId_MphDisconnectReq] = GsmL1_PrimId_MphDisconnectCnf, - [GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf, - [GsmL1_PrimId_MphDeactivateReq] = GsmL1_PrimId_MphDeactivateCnf, - [GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf, - [GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf, -}; - -const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { - [SuperFemto_PrimId_SystemInfoReq] = L1P_T_REQ, - [SuperFemto_PrimId_SystemInfoCnf] = L1P_T_CONF, - [SuperFemto_PrimId_SystemFailureInd] = L1P_T_IND, - [SuperFemto_PrimId_ActivateRfReq] = L1P_T_REQ, - [SuperFemto_PrimId_ActivateRfCnf] = L1P_T_CONF, - [SuperFemto_PrimId_DeactivateRfReq] = L1P_T_REQ, - [SuperFemto_PrimId_DeactivateRfCnf] = L1P_T_CONF, - [SuperFemto_PrimId_SetTraceFlagsReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockInfoReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockInfoCnf] = L1P_T_CONF, - [SuperFemto_PrimId_RfClockSetupReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockSetupCnf] = L1P_T_CONF, - [SuperFemto_PrimId_Layer1ResetReq] = L1P_T_REQ, - [SuperFemto_PrimId_Layer1ResetCnf] = L1P_T_CONF, -}; - -const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { - { SuperFemto_PrimId_SystemInfoReq, "SYSTEM-INFO.req" }, - { SuperFemto_PrimId_SystemInfoCnf, "SYSTEM-INFO.conf" }, - { SuperFemto_PrimId_SystemFailureInd, "SYSTEM-FAILURE.ind" }, - { SuperFemto_PrimId_ActivateRfReq, "ACTIVATE-RF.req" }, - { SuperFemto_PrimId_ActivateRfCnf, "ACTIVATE-RF.conf" }, - { SuperFemto_PrimId_DeactivateRfReq, "DEACTIVATE-RF.req" }, - { SuperFemto_PrimId_DeactivateRfCnf, "DEACTIVATE-RF.conf" }, - { SuperFemto_PrimId_SetTraceFlagsReq, "SET-TRACE-FLAGS.req" }, - { SuperFemto_PrimId_RfClockInfoReq, "RF-CLOCK-INFO.req" }, - { SuperFemto_PrimId_RfClockInfoCnf, "RF-CLOCK-INFO.conf" }, - { SuperFemto_PrimId_RfClockSetupReq, "RF-CLOCK-SETUP.req" }, - { SuperFemto_PrimId_RfClockSetupCnf, "RF-CLOCK-SETUP.conf" }, - { SuperFemto_PrimId_Layer1ResetReq, "LAYER1-RESET.req" }, - { SuperFemto_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" }, - { 0, NULL } -}; - -const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { - [SuperFemto_PrimId_SystemInfoReq] = SuperFemto_PrimId_SystemInfoCnf, - [SuperFemto_PrimId_ActivateRfReq] = SuperFemto_PrimId_ActivateRfCnf, - [SuperFemto_PrimId_DeactivateRfReq] = SuperFemto_PrimId_DeactivateRfCnf, - [SuperFemto_PrimId_RfClockInfoReq] = SuperFemto_PrimId_RfClockInfoCnf, - [SuperFemto_PrimId_RfClockSetupReq] = SuperFemto_PrimId_RfClockSetupCnf, - [SuperFemto_PrimId_Layer1ResetReq] = SuperFemto_PrimId_Layer1ResetCnf, -}; - -const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { - { GsmL1_Sapi_Fcch, "FCCH" }, - { GsmL1_Sapi_Sch, "SCH" }, - { GsmL1_Sapi_Sacch, "SACCH" }, - { GsmL1_Sapi_Sdcch, "SDCCH" }, - { GsmL1_Sapi_Bcch, "BCCH" }, - { GsmL1_Sapi_Pch, "PCH" }, - { GsmL1_Sapi_Agch, "AGCH" }, - { GsmL1_Sapi_Cbch, "CBCH" }, - { GsmL1_Sapi_Rach, "RACH" }, - { GsmL1_Sapi_TchF, "TCH/F" }, - { GsmL1_Sapi_FacchF, "FACCH/F" }, - { GsmL1_Sapi_TchH, "TCH/H" }, - { GsmL1_Sapi_FacchH, "FACCH/H" }, - { GsmL1_Sapi_Nch, "NCH" }, - { GsmL1_Sapi_Pdtch, "PDTCH" }, - { GsmL1_Sapi_Pacch, "PACCH" }, - { GsmL1_Sapi_Pbcch, "PBCCH" }, - { GsmL1_Sapi_Pagch, "PAGCH" }, - { GsmL1_Sapi_Ppch, "PPCH" }, - { GsmL1_Sapi_Pnch, "PNCH" }, - { GsmL1_Sapi_Ptcch, "PTCCH" }, - { GsmL1_Sapi_Prach, "PRACH" }, - { 0, NULL } -}; - -const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1] = { - { GsmL1_Status_Success, "Success" }, - { GsmL1_Status_Generic, "Generic error" }, - { GsmL1_Status_NoMemory, "Not enough memory" }, - { GsmL1_Status_Timeout, "Timeout" }, - { GsmL1_Status_InvalidParam, "Invalid parameter" }, - { GsmL1_Status_Busy, "Resource busy" }, - { GsmL1_Status_NoRessource, "No more resources" }, - { GsmL1_Status_Uninitialized, "Trying to use uninitialized resource" }, - { GsmL1_Status_NullInterface, "Trying to call a NULL interface" }, - { GsmL1_Status_NullFctnPtr, "Trying to call a NULL function ptr" }, - { GsmL1_Status_BadCrc, "Bad CRC" }, - { GsmL1_Status_BadUsf, "Bad USF" }, - { GsmL1_Status_InvalidCPS, "Invalid CPS field" }, - { GsmL1_Status_UnexpectedBurst, "Unexpected burst" }, - { GsmL1_Status_UnavailCodec, "AMR codec is unavailable" }, - { GsmL1_Status_CriticalError, "Critical error" }, - { GsmL1_Status_OverheatError, "Overheat error" }, - { GsmL1_Status_DeviceError, "Device error" }, - { GsmL1_Status_FacchError, "FACCH / TCH order error" }, - { GsmL1_Status_AlreadyDeactivated, "Lchan already deactivated" }, - { GsmL1_Status_TxBurstFifoOvrn, "FIFO overrun" }, - { GsmL1_Status_TxBurstFifoUndr, "FIFO underrun" }, - { GsmL1_Status_NotSynchronized, "Not synchronized" }, - { GsmL1_Status_Unsupported, "Unsupported feature" }, - { 0, NULL } -}; - -const struct value_string femtobts_tracef_names[29] = { - { DBG_DEBUG, "DEBUG" }, - { DBG_L1WARNING, "L1_WARNING" }, - { DBG_ERROR, "ERROR" }, - { DBG_L1RXMSG, "L1_RX_MSG" }, - { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE" }, - { DBG_L1TXMSG, "L1_TX_MSG" }, - { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE" }, - { DBG_MPHCNF, "MPH_CNF" }, - { DBG_MPHIND, "MPH_IND" }, - { DBG_MPHREQ, "MPH_REQ" }, - { DBG_PHIND, "PH_IND" }, - { DBG_PHREQ, "PH_REQ" }, - { DBG_PHYRF, "PHY_RF" }, - { DBG_PHYRFMSGBYTE, "PHY_MSG_BYTE" }, - { DBG_MODE, "MODE" }, - { DBG_TDMAINFO, "TDMA_INFO" }, - { DBG_BADCRC, "BAD_CRC" }, - { DBG_PHINDBYTE, "PH_IND_BYTE" }, - { DBG_PHREQBYTE, "PH_REQ_BYTE" }, - { DBG_DEVICEMSG, "DEVICE_MSG" }, - { DBG_RACHINFO, "RACH_INFO" }, - { DBG_LOGCHINFO, "LOG_CH_INFO" }, - { DBG_MEMORY, "MEMORY" }, - { DBG_PROFILING, "PROFILING" }, - { DBG_TESTCOMMENT, "TEST_COMMENT" }, - { DBG_TEST, "TEST" }, - { DBG_STATUS, "STATUS" }, - { 0, NULL } -}; - -const struct value_string femtobts_tch_pl_names[] = { - { GsmL1_TchPlType_NA, "N/A" }, - { GsmL1_TchPlType_Fr, "FR" }, - { GsmL1_TchPlType_Hr, "HR" }, - { GsmL1_TchPlType_Efr, "EFR" }, - { GsmL1_TchPlType_Amr, "AMR(IF2)" }, - { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" }, - { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" }, - { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" }, - { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" }, - { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" }, - { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" }, - { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" }, - { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" }, - { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" }, - { 0, NULL } -}; - -const struct value_string femtobts_dir_names[] = { - { GsmL1_Dir_TxDownlink, "TxDL" }, - { GsmL1_Dir_TxUplink, "TxUL" }, - { GsmL1_Dir_RxUplink, "RxUL" }, - { GsmL1_Dir_RxDownlink, "RxDL" }, - { GsmL1_Dir_TxDownlink|GsmL1_Dir_RxUplink, "BOTH" }, - { 0, NULL } -}; - -const struct value_string femtobts_chcomb_names[] = { - { GsmL1_LogChComb_0, "dummy" }, - { GsmL1_LogChComb_I, "tch_f" }, - { GsmL1_LogChComb_II, "tch_h" }, - { GsmL1_LogChComb_IV, "ccch" }, - { GsmL1_LogChComb_V, "ccch_sdcch4" }, - { GsmL1_LogChComb_VII, "sdcch8" }, - { GsmL1_LogChComb_XIII, "pdtch" }, - { 0, NULL } -}; - -const uint8_t pdch_msu_size[_NUM_PDCH_CS] = { - [PDCH_CS_1] = 23, - [PDCH_CS_2] = 34, - [PDCH_CS_3] = 40, - [PDCH_CS_4] = 54, - [PDCH_MCS_1] = 27, - [PDCH_MCS_2] = 33, - [PDCH_MCS_3] = 42, - [PDCH_MCS_4] = 49, - [PDCH_MCS_5] = 60, - [PDCH_MCS_6] = 78, - [PDCH_MCS_7] = 118, - [PDCH_MCS_8] = 142, - [PDCH_MCS_9] = 154 -}; diff --git a/src/femtobts.h b/src/femtobts.h deleted file mode 100644 index 7e45578..0000000 --- a/src/femtobts.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FEMTOBTS_H -#define FEMTOBTS_H - -#include -#include - -#include -#include - -#ifdef L1_HAS_RTP_MODE -/* This is temporarily disabled, as AMR has some bugs in RTP mode */ -//#define USE_L1_RTP_MODE /* Tell L1 to use RTP mode */ -#endif - -enum l1prim_type { - L1P_T_REQ, - L1P_T_CONF, - L1P_T_IND, -}; - -const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM]; -const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1]; -const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM]; - -const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM]; -const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1]; -const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM]; - -const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1]; -const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1]; - -const struct value_string femtobts_tracef_names[29]; - -const struct value_string femtobts_tch_pl_names[15]; - -const struct value_string femtobts_dir_names[6]; - -enum pdch_cs { - PDCH_CS_1, - PDCH_CS_2, - PDCH_CS_3, - PDCH_CS_4, - PDCH_MCS_1, - PDCH_MCS_2, - PDCH_MCS_3, - PDCH_MCS_4, - PDCH_MCS_5, - PDCH_MCS_6, - PDCH_MCS_7, - PDCH_MCS_8, - PDCH_MCS_9, - _NUM_PDCH_CS -}; - -const uint8_t pdch_msu_size[_NUM_PDCH_CS]; - -#endif /* FEMTOBTS_H */ diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c new file mode 100644 index 0000000..f6957d2 --- /dev/null +++ b/src/osmo-bts-sysmo/femtobts.c @@ -0,0 +1,275 @@ +/* sysmocom femtobts L1 API related definitions */ + +/* (C) 2011 by Harald Welte + * + * 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 "femtobts.h" + +const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM] = { + [GsmL1_PrimId_MphInitReq] = L1P_T_REQ, + [GsmL1_PrimId_MphCloseReq] = L1P_T_REQ, + [GsmL1_PrimId_MphConnectReq] = L1P_T_REQ, + [GsmL1_PrimId_MphDisconnectReq] = L1P_T_REQ, + [GsmL1_PrimId_MphActivateReq] = L1P_T_REQ, + [GsmL1_PrimId_MphDeactivateReq] = L1P_T_REQ, + [GsmL1_PrimId_MphConfigReq] = L1P_T_REQ, + [GsmL1_PrimId_MphMeasureReq] = L1P_T_REQ, + [GsmL1_PrimId_MphInitCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphCloseCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphConnectCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphDisconnectCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphActivateCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphDeactivateCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphConfigCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphMeasureCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphTimeInd] = L1P_T_IND, + [GsmL1_PrimId_MphSyncInd] = L1P_T_IND, + [GsmL1_PrimId_PhEmptyFrameReq] = L1P_T_REQ, + [GsmL1_PrimId_PhDataReq] = L1P_T_REQ, + [GsmL1_PrimId_PhConnectInd] = L1P_T_IND, + [GsmL1_PrimId_PhReadyToSendInd] = L1P_T_IND, + [GsmL1_PrimId_PhDataInd] = L1P_T_IND, + [GsmL1_PrimId_PhRaInd] = L1P_T_IND, +}; + +const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1] = { + { GsmL1_PrimId_MphInitReq, "MPH-INIT.req" }, + { GsmL1_PrimId_MphCloseReq, "MPH-CLOSE.req" }, + { GsmL1_PrimId_MphConnectReq, "MPH-CONNECT.req" }, + { GsmL1_PrimId_MphDisconnectReq,"MPH-DISCONNECT.req" }, + { GsmL1_PrimId_MphActivateReq, "MPH-ACTIVATE.req" }, + { GsmL1_PrimId_MphDeactivateReq,"MPH-DEACTIVATE.req" }, + { GsmL1_PrimId_MphConfigReq, "MPH-CONFIG.req" }, + { GsmL1_PrimId_MphMeasureReq, "MPH-MEASURE.req" }, + { GsmL1_PrimId_MphInitCnf, "MPH-INIT.conf" }, + { GsmL1_PrimId_MphCloseCnf, "MPH-CLOSE.conf" }, + { GsmL1_PrimId_MphConnectCnf, "MPH-CONNECT.conf" }, + { GsmL1_PrimId_MphDisconnectCnf,"MPH-DISCONNECT.conf" }, + { GsmL1_PrimId_MphActivateCnf, "MPH-ACTIVATE.conf" }, + { GsmL1_PrimId_MphDeactivateCnf,"MPH-DEACTIVATE.conf" }, + { GsmL1_PrimId_MphConfigCnf, "MPH-CONFIG.conf" }, + { GsmL1_PrimId_MphMeasureCnf, "MPH-MEASURE.conf" }, + { GsmL1_PrimId_MphTimeInd, "MPH-TIME.ind" }, + { GsmL1_PrimId_MphSyncInd, "MPH-SYNC.ind" }, + { GsmL1_PrimId_PhEmptyFrameReq, "PH-EMPTY_FRAME.req" }, + { GsmL1_PrimId_PhDataReq, "PH-DATA.req" }, + { GsmL1_PrimId_PhConnectInd, "PH-CONNECT.ind" }, + { GsmL1_PrimId_PhReadyToSendInd,"PH-READY_TO_SEND.ind" }, + { GsmL1_PrimId_PhDataInd, "PH-DATA.ind" }, + { GsmL1_PrimId_PhRaInd, "PH-RA.ind" }, + { 0, NULL } +}; + +const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM] = { + [GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf, + [GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf, + [GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf, + [GsmL1_PrimId_MphDisconnectReq] = GsmL1_PrimId_MphDisconnectCnf, + [GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf, + [GsmL1_PrimId_MphDeactivateReq] = GsmL1_PrimId_MphDeactivateCnf, + [GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf, + [GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf, +}; + +const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { + [SuperFemto_PrimId_SystemInfoReq] = L1P_T_REQ, + [SuperFemto_PrimId_SystemInfoCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SystemFailureInd] = L1P_T_IND, + [SuperFemto_PrimId_ActivateRfReq] = L1P_T_REQ, + [SuperFemto_PrimId_ActivateRfCnf] = L1P_T_CONF, + [SuperFemto_PrimId_DeactivateRfReq] = L1P_T_REQ, + [SuperFemto_PrimId_DeactivateRfCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SetTraceFlagsReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockInfoReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockInfoCnf] = L1P_T_CONF, + [SuperFemto_PrimId_RfClockSetupReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockSetupCnf] = L1P_T_CONF, + [SuperFemto_PrimId_Layer1ResetReq] = L1P_T_REQ, + [SuperFemto_PrimId_Layer1ResetCnf] = L1P_T_CONF, +}; + +const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { + { SuperFemto_PrimId_SystemInfoReq, "SYSTEM-INFO.req" }, + { SuperFemto_PrimId_SystemInfoCnf, "SYSTEM-INFO.conf" }, + { SuperFemto_PrimId_SystemFailureInd, "SYSTEM-FAILURE.ind" }, + { SuperFemto_PrimId_ActivateRfReq, "ACTIVATE-RF.req" }, + { SuperFemto_PrimId_ActivateRfCnf, "ACTIVATE-RF.conf" }, + { SuperFemto_PrimId_DeactivateRfReq, "DEACTIVATE-RF.req" }, + { SuperFemto_PrimId_DeactivateRfCnf, "DEACTIVATE-RF.conf" }, + { SuperFemto_PrimId_SetTraceFlagsReq, "SET-TRACE-FLAGS.req" }, + { SuperFemto_PrimId_RfClockInfoReq, "RF-CLOCK-INFO.req" }, + { SuperFemto_PrimId_RfClockInfoCnf, "RF-CLOCK-INFO.conf" }, + { SuperFemto_PrimId_RfClockSetupReq, "RF-CLOCK-SETUP.req" }, + { SuperFemto_PrimId_RfClockSetupCnf, "RF-CLOCK-SETUP.conf" }, + { SuperFemto_PrimId_Layer1ResetReq, "LAYER1-RESET.req" }, + { SuperFemto_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" }, + { 0, NULL } +}; + +const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { + [SuperFemto_PrimId_SystemInfoReq] = SuperFemto_PrimId_SystemInfoCnf, + [SuperFemto_PrimId_ActivateRfReq] = SuperFemto_PrimId_ActivateRfCnf, + [SuperFemto_PrimId_DeactivateRfReq] = SuperFemto_PrimId_DeactivateRfCnf, + [SuperFemto_PrimId_RfClockInfoReq] = SuperFemto_PrimId_RfClockInfoCnf, + [SuperFemto_PrimId_RfClockSetupReq] = SuperFemto_PrimId_RfClockSetupCnf, + [SuperFemto_PrimId_Layer1ResetReq] = SuperFemto_PrimId_Layer1ResetCnf, +}; + +const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { + { GsmL1_Sapi_Fcch, "FCCH" }, + { GsmL1_Sapi_Sch, "SCH" }, + { GsmL1_Sapi_Sacch, "SACCH" }, + { GsmL1_Sapi_Sdcch, "SDCCH" }, + { GsmL1_Sapi_Bcch, "BCCH" }, + { GsmL1_Sapi_Pch, "PCH" }, + { GsmL1_Sapi_Agch, "AGCH" }, + { GsmL1_Sapi_Cbch, "CBCH" }, + { GsmL1_Sapi_Rach, "RACH" }, + { GsmL1_Sapi_TchF, "TCH/F" }, + { GsmL1_Sapi_FacchF, "FACCH/F" }, + { GsmL1_Sapi_TchH, "TCH/H" }, + { GsmL1_Sapi_FacchH, "FACCH/H" }, + { GsmL1_Sapi_Nch, "NCH" }, + { GsmL1_Sapi_Pdtch, "PDTCH" }, + { GsmL1_Sapi_Pacch, "PACCH" }, + { GsmL1_Sapi_Pbcch, "PBCCH" }, + { GsmL1_Sapi_Pagch, "PAGCH" }, + { GsmL1_Sapi_Ppch, "PPCH" }, + { GsmL1_Sapi_Pnch, "PNCH" }, + { GsmL1_Sapi_Ptcch, "PTCCH" }, + { GsmL1_Sapi_Prach, "PRACH" }, + { 0, NULL } +}; + +const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1] = { + { GsmL1_Status_Success, "Success" }, + { GsmL1_Status_Generic, "Generic error" }, + { GsmL1_Status_NoMemory, "Not enough memory" }, + { GsmL1_Status_Timeout, "Timeout" }, + { GsmL1_Status_InvalidParam, "Invalid parameter" }, + { GsmL1_Status_Busy, "Resource busy" }, + { GsmL1_Status_NoRessource, "No more resources" }, + { GsmL1_Status_Uninitialized, "Trying to use uninitialized resource" }, + { GsmL1_Status_NullInterface, "Trying to call a NULL interface" }, + { GsmL1_Status_NullFctnPtr, "Trying to call a NULL function ptr" }, + { GsmL1_Status_BadCrc, "Bad CRC" }, + { GsmL1_Status_BadUsf, "Bad USF" }, + { GsmL1_Status_InvalidCPS, "Invalid CPS field" }, + { GsmL1_Status_UnexpectedBurst, "Unexpected burst" }, + { GsmL1_Status_UnavailCodec, "AMR codec is unavailable" }, + { GsmL1_Status_CriticalError, "Critical error" }, + { GsmL1_Status_OverheatError, "Overheat error" }, + { GsmL1_Status_DeviceError, "Device error" }, + { GsmL1_Status_FacchError, "FACCH / TCH order error" }, + { GsmL1_Status_AlreadyDeactivated, "Lchan already deactivated" }, + { GsmL1_Status_TxBurstFifoOvrn, "FIFO overrun" }, + { GsmL1_Status_TxBurstFifoUndr, "FIFO underrun" }, + { GsmL1_Status_NotSynchronized, "Not synchronized" }, + { GsmL1_Status_Unsupported, "Unsupported feature" }, + { 0, NULL } +}; + +const struct value_string femtobts_tracef_names[29] = { + { DBG_DEBUG, "DEBUG" }, + { DBG_L1WARNING, "L1_WARNING" }, + { DBG_ERROR, "ERROR" }, + { DBG_L1RXMSG, "L1_RX_MSG" }, + { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE" }, + { DBG_L1TXMSG, "L1_TX_MSG" }, + { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE" }, + { DBG_MPHCNF, "MPH_CNF" }, + { DBG_MPHIND, "MPH_IND" }, + { DBG_MPHREQ, "MPH_REQ" }, + { DBG_PHIND, "PH_IND" }, + { DBG_PHREQ, "PH_REQ" }, + { DBG_PHYRF, "PHY_RF" }, + { DBG_PHYRFMSGBYTE, "PHY_MSG_BYTE" }, + { DBG_MODE, "MODE" }, + { DBG_TDMAINFO, "TDMA_INFO" }, + { DBG_BADCRC, "BAD_CRC" }, + { DBG_PHINDBYTE, "PH_IND_BYTE" }, + { DBG_PHREQBYTE, "PH_REQ_BYTE" }, + { DBG_DEVICEMSG, "DEVICE_MSG" }, + { DBG_RACHINFO, "RACH_INFO" }, + { DBG_LOGCHINFO, "LOG_CH_INFO" }, + { DBG_MEMORY, "MEMORY" }, + { DBG_PROFILING, "PROFILING" }, + { DBG_TESTCOMMENT, "TEST_COMMENT" }, + { DBG_TEST, "TEST" }, + { DBG_STATUS, "STATUS" }, + { 0, NULL } +}; + +const struct value_string femtobts_tch_pl_names[] = { + { GsmL1_TchPlType_NA, "N/A" }, + { GsmL1_TchPlType_Fr, "FR" }, + { GsmL1_TchPlType_Hr, "HR" }, + { GsmL1_TchPlType_Efr, "EFR" }, + { GsmL1_TchPlType_Amr, "AMR(IF2)" }, + { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" }, + { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" }, + { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" }, + { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" }, + { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" }, + { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" }, + { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" }, + { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" }, + { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" }, + { 0, NULL } +}; + +const struct value_string femtobts_dir_names[] = { + { GsmL1_Dir_TxDownlink, "TxDL" }, + { GsmL1_Dir_TxUplink, "TxUL" }, + { GsmL1_Dir_RxUplink, "RxUL" }, + { GsmL1_Dir_RxDownlink, "RxDL" }, + { GsmL1_Dir_TxDownlink|GsmL1_Dir_RxUplink, "BOTH" }, + { 0, NULL } +}; + +const struct value_string femtobts_chcomb_names[] = { + { GsmL1_LogChComb_0, "dummy" }, + { GsmL1_LogChComb_I, "tch_f" }, + { GsmL1_LogChComb_II, "tch_h" }, + { GsmL1_LogChComb_IV, "ccch" }, + { GsmL1_LogChComb_V, "ccch_sdcch4" }, + { GsmL1_LogChComb_VII, "sdcch8" }, + { GsmL1_LogChComb_XIII, "pdtch" }, + { 0, NULL } +}; + +const uint8_t pdch_msu_size[_NUM_PDCH_CS] = { + [PDCH_CS_1] = 23, + [PDCH_CS_2] = 34, + [PDCH_CS_3] = 40, + [PDCH_CS_4] = 54, + [PDCH_MCS_1] = 27, + [PDCH_MCS_2] = 33, + [PDCH_MCS_3] = 42, + [PDCH_MCS_4] = 49, + [PDCH_MCS_5] = 60, + [PDCH_MCS_6] = 78, + [PDCH_MCS_7] = 118, + [PDCH_MCS_8] = 142, + [PDCH_MCS_9] = 154 +}; diff --git a/src/osmo-bts-sysmo/femtobts.h b/src/osmo-bts-sysmo/femtobts.h new file mode 100644 index 0000000..7e45578 --- /dev/null +++ b/src/osmo-bts-sysmo/femtobts.h @@ -0,0 +1,57 @@ +#ifndef FEMTOBTS_H +#define FEMTOBTS_H + +#include +#include + +#include +#include + +#ifdef L1_HAS_RTP_MODE +/* This is temporarily disabled, as AMR has some bugs in RTP mode */ +//#define USE_L1_RTP_MODE /* Tell L1 to use RTP mode */ +#endif + +enum l1prim_type { + L1P_T_REQ, + L1P_T_CONF, + L1P_T_IND, +}; + +const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM]; +const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1]; +const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM]; + +const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM]; +const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1]; +const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM]; + +const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1]; +const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1]; + +const struct value_string femtobts_tracef_names[29]; + +const struct value_string femtobts_tch_pl_names[15]; + +const struct value_string femtobts_dir_names[6]; + +enum pdch_cs { + PDCH_CS_1, + PDCH_CS_2, + PDCH_CS_3, + PDCH_CS_4, + PDCH_MCS_1, + PDCH_MCS_2, + PDCH_MCS_3, + PDCH_MCS_4, + PDCH_MCS_5, + PDCH_MCS_6, + PDCH_MCS_7, + PDCH_MCS_8, + PDCH_MCS_9, + _NUM_PDCH_CS +}; + +const uint8_t pdch_msu_size[_NUM_PDCH_CS]; + +#endif /* FEMTOBTS_H */ diff --git a/src/osmo-bts-sysmo/sysmo_l1_fwd.c b/src/osmo-bts-sysmo/sysmo_l1_fwd.c new file mode 100644 index 0000000..535a7f0 --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_fwd.c @@ -0,0 +1,145 @@ +/* Interface handler for Sysmocom L1 (forwarding) */ + +/* (C) 2011 by Harald Welte + * + * 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 +#include +#include +#include + +#include "gprs_debug.h" +#include "sysmo_l1_if.h" + + +#define L1FWD_L1_PORT 9999 +#define L1FWD_SYS_PORT 9998 +#define L1FWD_TCH_PORT 9997 +#define L1FWD_PDTCH_PORT 9996 + +static const uint16_t fwd_udp_ports[] = { + [MQ_SYS_WRITE] = L1FWD_SYS_PORT, + [MQ_L1_WRITE] = L1FWD_L1_PORT, + [MQ_TCH_WRITE] = L1FWD_TCH_PORT, + [MQ_PDTCH_WRITE]= L1FWD_PDTCH_PORT, +}; + +static int fwd_read_cb(struct osmo_fd *ofd) +{ + struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, + 128, "udp_rx"); + struct femtol1_hdl *fl1h = ofd->data; + int rc; + + if (!msg) + return -ENOMEM; + + msg->l1h = msg->data; + rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); + if (rc < 0) { + LOGP(DL1IF, LOGL_ERROR, "Short read from UDP\n"); + msgb_free(msg); + return rc; + } else if (rc == 0) { + LOGP(DL1IF, LOGL_ERROR, "Len=0 from UDP\n"); + msgb_free(msg); + return rc; + } + msgb_put(msg, rc); + + if (ofd->priv_nr == MQ_SYS_WRITE) + rc = l1if_handle_sysprim(fl1h, msg); + else + rc = l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); + + return rc; +} + +static int prim_write_cb(struct osmo_fd *ofd, struct msgb *msg) +{ + /* write to the fd */ + return write(ofd->fd, msg->head, msg->len); +} + +int l1if_transport_open(int q, struct femtol1_hdl *fl1h) +{ + int rc; + char *bts_host = getenv("L1FWD_BTS_HOST"); + + printf("sizeof(GsmL1_Prim_t) = %zu\n", sizeof(GsmL1_Prim_t)); + printf("sizeof(SuperFemto_Prim_t) = %zu\n", sizeof(SuperFemto_Prim_t)); + + if (!bts_host) { + fprintf(stderr, "You have to set the L1FWD_BTS_HOST environment variable\n"); + exit(2); + } + + struct osmo_wqueue *wq = &fl1h->write_q[q]; + struct osmo_fd *ofd = &wq->bfd; + + osmo_wqueue_init(wq, 10); + wq->write_cb = prim_write_cb; + wq->read_cb = fwd_read_cb; + + ofd->data = fl1h; + ofd->priv_nr = q; + ofd->when |= BSC_FD_READ; + + rc = osmo_sock_init_ofd(ofd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, + bts_host, fwd_udp_ports[q], + OSMO_SOCK_F_CONNECT); + if (rc < 0) + return rc; + + return 0; +} + +int l1if_transport_close(int q, struct femtol1_hdl *fl1h) +{ + struct osmo_wqueue *wq = &fl1h->write_q[q]; + struct osmo_fd *ofd = &wq->bfd; + + osmo_wqueue_clear(wq); + osmo_fd_unregister(ofd); + close(ofd->fd); + + return 0; +} diff --git a/src/osmo-bts-sysmo/sysmo_l1_hw.c b/src/osmo-bts-sysmo/sysmo_l1_hw.c new file mode 100644 index 0000000..2c019be --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_hw.c @@ -0,0 +1,216 @@ +/* Interface handler for Sysmocom L1 (real hardware) */ + +/* (C) 2011 by Harald Welte + * + * 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 "gprs_debug.h" +#include "femtobts.h" +#include "sysmo_l1_if.h" + + +#ifdef HW_SYSMOBTS_V1 +#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/femtobts_dsp2arm" +#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/femtobts_arm2dsp" +#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_dsp2arm" +#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_arm2dsp" +#else +#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/superfemto_dsp2arm" +#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/superfemto_arm2dsp" +#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_sig_dsp2arm" +#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_sig_arm2dsp" + +#define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" +#define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" +#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm1" //2 -- trx1 +#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp1" //2 +#endif + +static const char *rd_devnames[] = { + [MQ_SYS_READ] = DEV_SYS_DSP2ARM_NAME, + [MQ_L1_READ] = DEV_L1_DSP2ARM_NAME, +#ifndef HW_SYSMOBTS_V1 + [MQ_TCH_READ] = DEV_TCH_DSP2ARM_NAME, + [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME, +#endif +}; + +static const char *wr_devnames[] = { + [MQ_SYS_WRITE] = DEV_SYS_ARM2DSP_NAME, + [MQ_L1_WRITE] = DEV_L1_ARM2DSP_NAME, +#ifndef HW_SYSMOBTS_V1 + [MQ_TCH_WRITE] = DEV_TCH_ARM2DSP_NAME, + [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME, +#endif +}; + +/* callback when there's something to read from the l1 msg_queue */ +static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what) +{ + //struct msgb *msg = l1p_msgb_alloc(); + struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, + 128, "1l_fd"); + struct femtol1_hdl *fl1h = ofd->data; + int rc; + + msg->l1h = msg->data; + rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); + if (rc < 0) { + if (rc != -1) + LOGP(DL1IF, LOGL_ERROR, "error reading from L1 msg_queue: %s\n", + strerror(errno)); + msgb_free(msg); + return rc; + } + msgb_put(msg, rc); + + switch (ofd->priv_nr) { + case MQ_SYS_WRITE: + if (rc != sizeof(SuperFemto_Prim_t)) + LOGP(DL1IF, LOGL_NOTICE, "%u != " + "sizeof(SuperFemto_Prim_t)\n", rc); + return l1if_handle_sysprim(fl1h, msg); + case MQ_L1_WRITE: +#ifndef HW_SYSMOBTS_V1 + case MQ_TCH_WRITE: + case MQ_PDTCH_WRITE: +#endif + if (rc != sizeof(GsmL1_Prim_t)) + LOGP(DL1IF, LOGL_NOTICE, "%u != " + "sizeof(GsmL1_Prim_t)\n", rc); + return l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); + default: + /* The compiler can't know that priv_nr is an enum. Assist. */ + LOGP(DL1IF, LOGL_FATAL, "writing on a wrong queue: %d\n", + ofd->priv_nr); + exit(0); + break; + } +}; + +/* callback when we can write to one of the l1 msg_queue devices */ +static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg) +{ + int rc; + + rc = write(ofd->fd, msg->l1h, msgb_l1len(msg)); + if (rc < 0) { + LOGP(DL1IF, LOGL_ERROR, "error writing to L1 msg_queue: %s\n", + strerror(errno)); + return rc; + } else if (rc < msg->len) { + LOGP(DL1IF, LOGL_ERROR, "short write to L1 msg_queue: " + "%u < %u\n", rc, msg->len); + return -EIO; + } + + return 0; +} + +int l1if_transport_open(int q, struct femtol1_hdl *hdl) +{ + int rc; + + /* Step 1: Open all msg_queue file descriptors */ + struct osmo_fd *read_ofd = &hdl->read_ofd[q]; + struct osmo_wqueue *wq = &hdl->write_q[q]; + struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; + + rc = open(rd_devnames[q], O_RDONLY); + if (rc < 0) { + LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", + strerror(errno)); + return rc; + } + read_ofd->fd = rc; + read_ofd->priv_nr = q; + read_ofd->data = hdl; + read_ofd->cb = l1if_fd_cb; + read_ofd->when = BSC_FD_READ; + rc = osmo_fd_register(read_ofd); + if (rc < 0) { + close(read_ofd->fd); + read_ofd->fd = -1; + return rc; + } + + rc = open(wr_devnames[q], O_WRONLY); + if (rc < 0) { + LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", + strerror(errno)); + goto out_read; + } + osmo_wqueue_init(wq, 10); + wq->write_cb = l1fd_write_cb; + write_ofd->fd = rc; + write_ofd->priv_nr = q; + write_ofd->data = hdl; + write_ofd->when = BSC_FD_WRITE; + rc = osmo_fd_register(write_ofd); + if (rc < 0) { + close(write_ofd->fd); + write_ofd->fd = -1; + goto out_read; + } + + return 0; + +out_read: + close(hdl->read_ofd[q].fd); + osmo_fd_unregister(&hdl->read_ofd[q]); + + return rc; +} + +int l1if_transport_close(int q, struct femtol1_hdl *hdl) +{ + struct osmo_fd *read_ofd = &hdl->read_ofd[q]; + struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; + + osmo_fd_unregister(read_ofd); + close(read_ofd->fd); + read_ofd->fd = -1; + + osmo_fd_unregister(write_ofd); + close(write_ofd->fd); + write_ofd->fd = -1; + + return 0; +} diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.c b/src/osmo-bts-sysmo/sysmo_l1_if.c new file mode 100644 index 0000000..8572786 --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_if.c @@ -0,0 +1,396 @@ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern void *tall_pcu_ctx; + +uint32_t l1if_ts_to_hLayer2(uint8_t trx, uint8_t ts) +{ + return (ts << 16) | (trx << 24); +} + +/* allocate a msgb containing a GsmL1_Prim_t */ +struct msgb *l1p_msgb_alloc(void) +{ + struct msgb *msg = msgb_alloc(sizeof(GsmL1_Prim_t), "l1_prim"); + + if (msg) + msg->l1h = msgb_put(msg, sizeof(GsmL1_Prim_t)); + + return msg; +} + +static int l1if_req_pdch(struct femtol1_hdl *fl1h, struct msgb *msg) +{ + struct osmo_wqueue *wqueue = &fl1h->write_q[MQ_PDTCH_WRITE]; + + if (osmo_wqueue_enqueue(wqueue, msg) != 0) { + LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); + msgb_free(msg); + } + + return 0; +} + +static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1) +{ + prim->id = id; + + /* for some reason the hLayer1 field is not always at the same position + * in the GsmL1_Prim_t, so we have to have this ugly case statement here... */ + switch (id) { + case GsmL1_PrimId_MphInitReq: + //prim->u.mphInitReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphCloseReq: + prim->u.mphCloseReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphConnectReq: + prim->u.mphConnectReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphDisconnectReq: + prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphActivateReq: + prim->u.mphActivateReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphDeactivateReq: + prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphConfigReq: + prim->u.mphConfigReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphMeasureReq: + prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphInitCnf: + case GsmL1_PrimId_MphCloseCnf: + case GsmL1_PrimId_MphConnectCnf: + case GsmL1_PrimId_MphDisconnectCnf: + case GsmL1_PrimId_MphActivateCnf: + case GsmL1_PrimId_MphDeactivateCnf: + case GsmL1_PrimId_MphConfigCnf: + case GsmL1_PrimId_MphMeasureCnf: + break; + case GsmL1_PrimId_MphTimeInd: + break; + case GsmL1_PrimId_MphSyncInd: + break; + case GsmL1_PrimId_PhEmptyFrameReq: + prim->u.phEmptyFrameReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_PhDataReq: + prim->u.phDataReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_PhConnectInd: + break; + case GsmL1_PrimId_PhReadyToSendInd: + break; + case GsmL1_PrimId_PhDataInd: + break; + case GsmL1_PrimId_PhRaInd: + break; + default: + LOGP(DL1IF, LOGL_ERROR, "unknown L1 primitive %u\n", id); + break; + } + return &prim->u; +} + +struct sapi_dir { + GsmL1_Sapi_t sapi; + GsmL1_Dir_t dir; +}; + +static const struct sapi_dir pdtch_sapis[] = { + { GsmL1_Sapi_Pdtch, GsmL1_Dir_TxDownlink }, + { GsmL1_Sapi_Pdtch, GsmL1_Dir_RxUplink }, + { GsmL1_Sapi_Ptcch, GsmL1_Dir_TxDownlink }, + { GsmL1_Sapi_Prach, GsmL1_Dir_RxUplink }, +#if 0 + { GsmL1_Sapi_Ptcch, GsmL1_Dir_RxUplink }, + { GsmL1_Sapi_Pacch, GsmL1_Dir_TxDownlink }, +#endif +}; + + +/* connect PDTCH */ +int l1if_connect_pdch(void *obj, uint8_t ts) +{ + struct femtol1_hdl *fl1h = obj; + struct msgb *msg = l1p_msgb_alloc(); + GsmL1_MphConnectReq_t *cr; + + cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h); + cr->u8Tn = ts; + cr->logChComb = GsmL1_LogChComb_XIII; + + return l1if_req_pdch(fl1h, msg); +} + +static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h, + GsmL1_PhReadyToSendInd_t *rts_ind) +{ + struct gsm_time g_time; + int rc = 0; + + gsm_fn2gsmtime(&g_time, rts_ind->u32Fn); + + DEBUGP(DL1IF, "Rx PH-RTS.ind %02u/%02u/%02u SAPI=%s\n", + g_time.t1, g_time.t2, g_time.t3, + get_value_string(femtobts_l1sapi_names, rts_ind->sapi)); + + switch (rts_ind->sapi) { + case GsmL1_Sapi_Pdtch: + case GsmL1_Sapi_Pacch: + rc = pcu_rx_rts_req_pdtch((long)fl1h->priv, rts_ind->u8Tn, + rts_ind->u16Arfcn, rts_ind->u32Fn, rts_ind->u8BlockNbr); + case GsmL1_Sapi_Ptcch: + // FIXME + default: + break; + } + + return rc; +} + +static void get_meas(struct pcu_l1_meas *meas, const GsmL1_MeasParam_t *l1_meas) +{ + meas->rssi = (int8_t) (l1_meas->fRssi); + meas->have_rssi = 1; + meas->ber = (uint8_t) (l1_meas->fBer * 100); + meas->have_ber = 1; + meas->bto = (int16_t) (l1_meas->i16BurstTiming); + meas->have_bto = 1; + meas->link_qual = (int16_t) (l1_meas->fLinkQuality); + meas->have_link_qual = 1; +} + +static int handle_ph_data_ind(struct femtol1_hdl *fl1h, + GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg) +{ + int rc = 0; + struct pcu_l1_meas meas = {0}; + + DEBUGP(DL1IF, "Rx PH-DATA.ind %s (hL2 %08x): %s\n", + get_value_string(femtobts_l1sapi_names, data_ind->sapi), + data_ind->hLayer2, + osmo_hexdump(data_ind->msgUnitParam.u8Buffer, + data_ind->msgUnitParam.u8Size)); + + pcu_rx_block_time(data_ind->u16Arfcn, data_ind->u32Fn, data_ind->u8Tn); + + /* + * TODO: Add proper bad frame handling here. This could be used + * to switch the used CS. Avoid a crash with the PCU right now + * feed "0 - 1" amount of data. + */ + if (data_ind->msgUnitParam.u8Size == 0) + return -1; + + gsmtap_send(fl1h->gsmtap, data_ind->u16Arfcn | GSMTAP_ARFCN_F_UPLINK, + data_ind->u8Tn, GSMTAP_CHANNEL_PACCH, 0, + data_ind->u32Fn, 0, 0, data_ind->msgUnitParam.u8Buffer+1, + data_ind->msgUnitParam.u8Size-1); + + get_meas(&meas, &data_ind->measParam); + + switch (data_ind->sapi) { + case GsmL1_Sapi_Pdtch: + case GsmL1_Sapi_Pacch: + /* drop incomplete UL block */ + if (data_ind->msgUnitParam.u8Buffer[0] + != GsmL1_PdtchPlType_Full) + break; + /* PDTCH / PACCH frame handling */ + pcu_rx_data_ind_pdtch((long)fl1h->priv, data_ind->u8Tn, + data_ind->msgUnitParam.u8Buffer + 1, + data_ind->msgUnitParam.u8Size - 1, + data_ind->u32Fn, + &meas); + break; + case GsmL1_Sapi_Ptcch: + // FIXME + break; + default: + LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n", + get_value_string(femtobts_l1sapi_names, data_ind->sapi)); + break; + } + + return rc; +} + +#define MIN_QUAL_RACH 5.0f + +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 + + return 0; +} + + +/* handle any random indication from the L1 */ +int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg) +{ + GsmL1_Prim_t *l1p = msgb_l1prim(msg); + int rc = 0; + + LOGP(DL1IF, LOGL_DEBUG, "Rx L1 prim %s on queue %d\n", + get_value_string(femtobts_l1prim_names, l1p->id), wq); + + switch (l1p->id) { +#if 0 + case GsmL1_PrimId_MphTimeInd: + rc = handle_mph_time_ind(fl1h, &l1p->u.mphTimeInd); + break; + case GsmL1_PrimId_MphSyncInd: + break; + case GsmL1_PrimId_PhConnectInd: + break; +#endif + case GsmL1_PrimId_PhReadyToSendInd: + rc = handle_ph_readytosend_ind(fl1h, &l1p->u.phReadyToSendInd); + break; + case GsmL1_PrimId_PhDataInd: + rc = handle_ph_data_ind(fl1h, &l1p->u.phDataInd, msg); + break; + case GsmL1_PrimId_PhRaInd: + rc = handle_ph_ra_ind(fl1h, &l1p->u.phRaInd); + break; + default: + break; + } + + msgb_free(msg); + + return rc; +} + +int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg) +{ + return -ENOTSUP; +} + +/* send packet data request to L1 */ +int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) +{ + struct femtol1_hdl *fl1h = obj; + struct msgb *msg; + GsmL1_Prim_t *l1p; + GsmL1_PhDataReq_t *data_req; + GsmL1_MsgUnitParam_t *msu_param; + struct gsm_time g_time; + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1IF, "TX packet data %02u/%02u/%02u is_ptcch=%d ts=%d " + "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, + g_time.t3, is_ptcch, ts, block_nr, arfcn, len); + + msg = l1p_msgb_alloc(); + l1p = msgb_l1prim(msg); + l1p->id = GsmL1_PrimId_PhDataReq; + data_req = &l1p->u.phDataReq; + data_req->hLayer1 = fl1h->hLayer1; + data_req->sapi = (is_ptcch) ? GsmL1_Sapi_Ptcch : GsmL1_Sapi_Pdtch; + data_req->subCh = GsmL1_SubCh_NA; + data_req->u8BlockNbr = block_nr; + data_req->u8Tn = ts; + data_req->u32Fn = fn; + msu_param = &data_req->msgUnitParam; + msu_param->u8Size = len; + memcpy(msu_param->u8Buffer, data, len); + + gsmtap_send(fl1h->gsmtap, arfcn, data_req->u8Tn, GSMTAP_CHANNEL_PACCH, + 0, data_req->u32Fn, 0, 0, + data_req->msgUnitParam.u8Buffer, + data_req->msgUnitParam.u8Size); + + + /* transmit */ + if (osmo_wqueue_enqueue(&fl1h->write_q[MQ_PDTCH_WRITE], msg) != 0) { + LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); + msgb_free(msg); + } + + return 0; +} + +void *l1if_open_pdch(void *priv, uint32_t hlayer1) +{ + struct femtol1_hdl *fl1h; + int rc; + + fl1h = talloc_zero(tall_pcu_ctx, struct femtol1_hdl); + if (!fl1h) + return NULL; + + fl1h->hLayer1 = hlayer1; + fl1h->priv = priv; + fl1h->clk_cal = 0; + /* default clock source: OCXO */ + fl1h->clk_src = SuperFemto_ClkSrcId_Ocxo; + + rc = l1if_transport_open(MQ_PDTCH_WRITE, fl1h); + if (rc < 0) { + talloc_free(fl1h); + return NULL; + } + + fl1h->gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 1); + if (fl1h->gsmtap) + gsmtap_source_add_sink(fl1h->gsmtap); + + return fl1h; +} + +int l1if_close_pdch(void *obj) +{ + struct femtol1_hdl *fl1h = obj; + if (fl1h) + l1if_transport_close(MQ_PDTCH_WRITE, fl1h); + talloc_free(fl1h); + return 0; +} + diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.h b/src/osmo-bts-sysmo/sysmo_l1_if.h new file mode 100644 index 0000000..6b50d4e --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_if.h @@ -0,0 +1,91 @@ +#ifndef _SYSMO_L1_IF_H +#define _SYSMO_L1_IF_H + +#include +#include +#include +#include +#include "femtobts.h" + +enum { + MQ_SYS_READ, + MQ_L1_READ, +#ifndef HW_SYSMOBTS_V1 + MQ_TCH_READ, + MQ_PDTCH_READ, +#endif + _NUM_MQ_READ +}; + +enum { + MQ_SYS_WRITE, + MQ_L1_WRITE, +#ifndef HW_SYSMOBTS_V1 + MQ_TCH_WRITE, + MQ_PDTCH_WRITE, +#endif + _NUM_MQ_WRITE +}; + +struct femtol1_hdl { + struct gsm_time gsm_time; + uint32_t hLayer1; /* handle to the L1 instance in the DSP */ + uint32_t dsp_trace_f; + int clk_cal; + uint8_t clk_src; + struct llist_head wlc_list; + + struct gsmtap_inst *gsmtap; + uint32_t gsmtap_sapi_mask; + + void *priv; /* user reference */ + + struct osmo_timer_list alive_timer; + unsigned int alive_prim_cnt; + + struct osmo_fd read_ofd[_NUM_MQ_READ]; /* osmo file descriptors */ + struct osmo_wqueue write_q[_NUM_MQ_WRITE]; + + struct { + uint8_t dsp_version[3]; + uint8_t fpga_version[3]; + uint32_t band_support; /* bitmask of GSM_BAND_* */ + } hw_info; +}; + +#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) +#define msgb_sysprim(msg) ((SuperFemto_Prim_t *)(msg)->l1h) + +typedef int l1if_compl_cb(struct msgb *l1_msg, void *data); + +/* send a request primitive to the L1 and schedule completion call-back */ +int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg, + int is_system_prim, l1if_compl_cb *cb, void *data); + +int l1if_reset(struct femtol1_hdl *hdl); +int l1if_activate_rf(struct femtol1_hdl *hdl, int on); +int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags); +int l1if_set_txpower(struct femtol1_hdl *fl1h, float tx_power); + +struct msgb *l1p_msgb_alloc(void); +struct msgb *sysp_msgb_alloc(void); + +uint32_t l1if_lchan_to_hLayer2(struct gsm_lchan *lchan); +struct gsm_lchan *l1if_hLayer2_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2); + +int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg); +int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg); + +/* tch.c */ +int l1if_tch_rx(struct gsm_lchan *lchan, 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); + +/* + * The implementation of these functions is selected by either compiling and + * linking sysmo_l1_hw.c or sysmo_l1_fwd.c + */ +int l1if_transport_open(int q, struct femtol1_hdl *hdl); +int l1if_transport_close(int q, struct femtol1_hdl *hdl); + +#endif /* _SYSMO_L1_IF_H */ diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp index b42f042..21a404f 100644 --- a/src/osmobts_sock.cpp +++ b/src/osmobts_sock.cpp @@ -100,7 +100,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) /* disable all slots, kick all TBFs */ for (trx = 0; trx < 8; trx++) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if (bts->trx[trx].fl1h) { l1if_close_pdch(bts->trx[trx].fl1h); bts->trx[trx].fl1h = NULL; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 9d7dbee..a19b957 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -124,7 +124,7 @@ static int pcu_tx_data_req(uint8_t trx, uint8_t ts, uint8_t sapi, void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY struct gprs_rlcmac_bts *bts = bts_main_data(); if (bts->trx[trx].fl1h) @@ -430,7 +430,7 @@ bssgp_failed: bts->trx[trx].arfcn = info_ind->trx[trx].arfcn; if ((info_ind->flags & PCU_IF_FLAG_SYSMO) && info_ind->trx[trx].hlayer1) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY LOGP(DL1IF, LOGL_DEBUG, " TRX %d hlayer1=%x\n", trx, info_ind->trx[trx].hlayer1); if (!bts->trx[trx].fl1h) @@ -455,7 +455,7 @@ bssgp_failed: if ((info_ind->trx[trx].pdch_mask & (1 << ts))) { /* FIXME: activate dynamically at RLCMAC */ if (!pdch->is_enabled()) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if ((info_ind->flags & PCU_IF_FLAG_SYSMO)) l1if_connect_pdch( diff --git a/src/sysmo_l1_fwd.c b/src/sysmo_l1_fwd.c deleted file mode 100644 index 535a7f0..0000000 --- a/src/sysmo_l1_fwd.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Interface handler for Sysmocom L1 (forwarding) */ - -/* (C) 2011 by Harald Welte - * - * 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 -#include -#include -#include - -#include "gprs_debug.h" -#include "sysmo_l1_if.h" - - -#define L1FWD_L1_PORT 9999 -#define L1FWD_SYS_PORT 9998 -#define L1FWD_TCH_PORT 9997 -#define L1FWD_PDTCH_PORT 9996 - -static const uint16_t fwd_udp_ports[] = { - [MQ_SYS_WRITE] = L1FWD_SYS_PORT, - [MQ_L1_WRITE] = L1FWD_L1_PORT, - [MQ_TCH_WRITE] = L1FWD_TCH_PORT, - [MQ_PDTCH_WRITE]= L1FWD_PDTCH_PORT, -}; - -static int fwd_read_cb(struct osmo_fd *ofd) -{ - struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, - 128, "udp_rx"); - struct femtol1_hdl *fl1h = ofd->data; - int rc; - - if (!msg) - return -ENOMEM; - - msg->l1h = msg->data; - rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); - if (rc < 0) { - LOGP(DL1IF, LOGL_ERROR, "Short read from UDP\n"); - msgb_free(msg); - return rc; - } else if (rc == 0) { - LOGP(DL1IF, LOGL_ERROR, "Len=0 from UDP\n"); - msgb_free(msg); - return rc; - } - msgb_put(msg, rc); - - if (ofd->priv_nr == MQ_SYS_WRITE) - rc = l1if_handle_sysprim(fl1h, msg); - else - rc = l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); - - return rc; -} - -static int prim_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - /* write to the fd */ - return write(ofd->fd, msg->head, msg->len); -} - -int l1if_transport_open(int q, struct femtol1_hdl *fl1h) -{ - int rc; - char *bts_host = getenv("L1FWD_BTS_HOST"); - - printf("sizeof(GsmL1_Prim_t) = %zu\n", sizeof(GsmL1_Prim_t)); - printf("sizeof(SuperFemto_Prim_t) = %zu\n", sizeof(SuperFemto_Prim_t)); - - if (!bts_host) { - fprintf(stderr, "You have to set the L1FWD_BTS_HOST environment variable\n"); - exit(2); - } - - struct osmo_wqueue *wq = &fl1h->write_q[q]; - struct osmo_fd *ofd = &wq->bfd; - - osmo_wqueue_init(wq, 10); - wq->write_cb = prim_write_cb; - wq->read_cb = fwd_read_cb; - - ofd->data = fl1h; - ofd->priv_nr = q; - ofd->when |= BSC_FD_READ; - - rc = osmo_sock_init_ofd(ofd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, - bts_host, fwd_udp_ports[q], - OSMO_SOCK_F_CONNECT); - if (rc < 0) - return rc; - - return 0; -} - -int l1if_transport_close(int q, struct femtol1_hdl *fl1h) -{ - struct osmo_wqueue *wq = &fl1h->write_q[q]; - struct osmo_fd *ofd = &wq->bfd; - - osmo_wqueue_clear(wq); - osmo_fd_unregister(ofd); - close(ofd->fd); - - return 0; -} diff --git a/src/sysmo_l1_hw.c b/src/sysmo_l1_hw.c deleted file mode 100644 index 8351d68..0000000 --- a/src/sysmo_l1_hw.c +++ /dev/null @@ -1,216 +0,0 @@ -/* Interface handler for Sysmocom L1 (real hardware) */ - -/* (C) 2011 by Harald Welte - * - * 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 "gprs_debug.h" -#include "femtobts.h" -#include "sysmo_l1_if.h" - - -#ifdef HW_SYSMOBTS_V1 -#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/femtobts_dsp2arm" -#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/femtobts_arm2dsp" -#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_dsp2arm" -#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_arm2dsp" -#else -#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/superfemto_dsp2arm" -#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/superfemto_arm2dsp" -#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_sig_dsp2arm" -#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_sig_arm2dsp" - -#define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" -#define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" -#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm" -#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp" -#endif - -static const char *rd_devnames[] = { - [MQ_SYS_READ] = DEV_SYS_DSP2ARM_NAME, - [MQ_L1_READ] = DEV_L1_DSP2ARM_NAME, -#ifndef HW_SYSMOBTS_V1 - [MQ_TCH_READ] = DEV_TCH_DSP2ARM_NAME, - [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME, -#endif -}; - -static const char *wr_devnames[] = { - [MQ_SYS_WRITE] = DEV_SYS_ARM2DSP_NAME, - [MQ_L1_WRITE] = DEV_L1_ARM2DSP_NAME, -#ifndef HW_SYSMOBTS_V1 - [MQ_TCH_WRITE] = DEV_TCH_ARM2DSP_NAME, - [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME, -#endif -}; - -/* callback when there's something to read from the l1 msg_queue */ -static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what) -{ - //struct msgb *msg = l1p_msgb_alloc(); - struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, - 128, "1l_fd"); - struct femtol1_hdl *fl1h = ofd->data; - int rc; - - msg->l1h = msg->data; - rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); - if (rc < 0) { - if (rc != -1) - LOGP(DL1IF, LOGL_ERROR, "error reading from L1 msg_queue: %s\n", - strerror(errno)); - msgb_free(msg); - return rc; - } - msgb_put(msg, rc); - - switch (ofd->priv_nr) { - case MQ_SYS_WRITE: - if (rc != sizeof(SuperFemto_Prim_t)) - LOGP(DL1IF, LOGL_NOTICE, "%u != " - "sizeof(SuperFemto_Prim_t)\n", rc); - return l1if_handle_sysprim(fl1h, msg); - case MQ_L1_WRITE: -#ifndef HW_SYSMOBTS_V1 - case MQ_TCH_WRITE: - case MQ_PDTCH_WRITE: -#endif - if (rc != sizeof(GsmL1_Prim_t)) - LOGP(DL1IF, LOGL_NOTICE, "%u != " - "sizeof(GsmL1_Prim_t)\n", rc); - return l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); - default: - /* The compiler can't know that priv_nr is an enum. Assist. */ - LOGP(DL1IF, LOGL_FATAL, "writing on a wrong queue: %d\n", - ofd->priv_nr); - exit(0); - break; - } -}; - -/* callback when we can write to one of the l1 msg_queue devices */ -static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - int rc; - - rc = write(ofd->fd, msg->l1h, msgb_l1len(msg)); - if (rc < 0) { - LOGP(DL1IF, LOGL_ERROR, "error writing to L1 msg_queue: %s\n", - strerror(errno)); - return rc; - } else if (rc < msg->len) { - LOGP(DL1IF, LOGL_ERROR, "short write to L1 msg_queue: " - "%u < %u\n", rc, msg->len); - return -EIO; - } - - return 0; -} - -int l1if_transport_open(int q, struct femtol1_hdl *hdl) -{ - int rc; - - /* Step 1: Open all msg_queue file descriptors */ - struct osmo_fd *read_ofd = &hdl->read_ofd[q]; - struct osmo_wqueue *wq = &hdl->write_q[q]; - struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; - - rc = open(rd_devnames[q], O_RDONLY); - if (rc < 0) { - LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", - strerror(errno)); - return rc; - } - read_ofd->fd = rc; - read_ofd->priv_nr = q; - read_ofd->data = hdl; - read_ofd->cb = l1if_fd_cb; - read_ofd->when = BSC_FD_READ; - rc = osmo_fd_register(read_ofd); - if (rc < 0) { - close(read_ofd->fd); - read_ofd->fd = -1; - return rc; - } - - rc = open(wr_devnames[q], O_WRONLY); - if (rc < 0) { - LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", - strerror(errno)); - goto out_read; - } - osmo_wqueue_init(wq, 10); - wq->write_cb = l1fd_write_cb; - write_ofd->fd = rc; - write_ofd->priv_nr = q; - write_ofd->data = hdl; - write_ofd->when = BSC_FD_WRITE; - rc = osmo_fd_register(write_ofd); - if (rc < 0) { - close(write_ofd->fd); - write_ofd->fd = -1; - goto out_read; - } - - return 0; - -out_read: - close(hdl->read_ofd[q].fd); - osmo_fd_unregister(&hdl->read_ofd[q]); - - return rc; -} - -int l1if_transport_close(int q, struct femtol1_hdl *hdl) -{ - struct osmo_fd *read_ofd = &hdl->read_ofd[q]; - struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; - - osmo_fd_unregister(read_ofd); - close(read_ofd->fd); - read_ofd->fd = -1; - - osmo_fd_unregister(write_ofd); - close(write_ofd->fd); - write_ofd->fd = -1; - - return 0; -} diff --git a/src/sysmo_l1_if.c b/src/sysmo_l1_if.c deleted file mode 100644 index 8572786..0000000 --- a/src/sysmo_l1_if.c +++ /dev/null @@ -1,396 +0,0 @@ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -extern void *tall_pcu_ctx; - -uint32_t l1if_ts_to_hLayer2(uint8_t trx, uint8_t ts) -{ - return (ts << 16) | (trx << 24); -} - -/* allocate a msgb containing a GsmL1_Prim_t */ -struct msgb *l1p_msgb_alloc(void) -{ - struct msgb *msg = msgb_alloc(sizeof(GsmL1_Prim_t), "l1_prim"); - - if (msg) - msg->l1h = msgb_put(msg, sizeof(GsmL1_Prim_t)); - - return msg; -} - -static int l1if_req_pdch(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - struct osmo_wqueue *wqueue = &fl1h->write_q[MQ_PDTCH_WRITE]; - - if (osmo_wqueue_enqueue(wqueue, msg) != 0) { - LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); - msgb_free(msg); - } - - return 0; -} - -static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1) -{ - prim->id = id; - - /* for some reason the hLayer1 field is not always at the same position - * in the GsmL1_Prim_t, so we have to have this ugly case statement here... */ - switch (id) { - case GsmL1_PrimId_MphInitReq: - //prim->u.mphInitReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphCloseReq: - prim->u.mphCloseReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphConnectReq: - prim->u.mphConnectReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphDisconnectReq: - prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphActivateReq: - prim->u.mphActivateReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphDeactivateReq: - prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphConfigReq: - prim->u.mphConfigReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphMeasureReq: - prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphInitCnf: - case GsmL1_PrimId_MphCloseCnf: - case GsmL1_PrimId_MphConnectCnf: - case GsmL1_PrimId_MphDisconnectCnf: - case GsmL1_PrimId_MphActivateCnf: - case GsmL1_PrimId_MphDeactivateCnf: - case GsmL1_PrimId_MphConfigCnf: - case GsmL1_PrimId_MphMeasureCnf: - break; - case GsmL1_PrimId_MphTimeInd: - break; - case GsmL1_PrimId_MphSyncInd: - break; - case GsmL1_PrimId_PhEmptyFrameReq: - prim->u.phEmptyFrameReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_PhDataReq: - prim->u.phDataReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_PhConnectInd: - break; - case GsmL1_PrimId_PhReadyToSendInd: - break; - case GsmL1_PrimId_PhDataInd: - break; - case GsmL1_PrimId_PhRaInd: - break; - default: - LOGP(DL1IF, LOGL_ERROR, "unknown L1 primitive %u\n", id); - break; - } - return &prim->u; -} - -struct sapi_dir { - GsmL1_Sapi_t sapi; - GsmL1_Dir_t dir; -}; - -static const struct sapi_dir pdtch_sapis[] = { - { GsmL1_Sapi_Pdtch, GsmL1_Dir_TxDownlink }, - { GsmL1_Sapi_Pdtch, GsmL1_Dir_RxUplink }, - { GsmL1_Sapi_Ptcch, GsmL1_Dir_TxDownlink }, - { GsmL1_Sapi_Prach, GsmL1_Dir_RxUplink }, -#if 0 - { GsmL1_Sapi_Ptcch, GsmL1_Dir_RxUplink }, - { GsmL1_Sapi_Pacch, GsmL1_Dir_TxDownlink }, -#endif -}; - - -/* connect PDTCH */ -int l1if_connect_pdch(void *obj, uint8_t ts) -{ - struct femtol1_hdl *fl1h = obj; - struct msgb *msg = l1p_msgb_alloc(); - GsmL1_MphConnectReq_t *cr; - - cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h); - cr->u8Tn = ts; - cr->logChComb = GsmL1_LogChComb_XIII; - - return l1if_req_pdch(fl1h, msg); -} - -static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h, - GsmL1_PhReadyToSendInd_t *rts_ind) -{ - struct gsm_time g_time; - int rc = 0; - - gsm_fn2gsmtime(&g_time, rts_ind->u32Fn); - - DEBUGP(DL1IF, "Rx PH-RTS.ind %02u/%02u/%02u SAPI=%s\n", - g_time.t1, g_time.t2, g_time.t3, - get_value_string(femtobts_l1sapi_names, rts_ind->sapi)); - - switch (rts_ind->sapi) { - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - rc = pcu_rx_rts_req_pdtch((long)fl1h->priv, rts_ind->u8Tn, - rts_ind->u16Arfcn, rts_ind->u32Fn, rts_ind->u8BlockNbr); - case GsmL1_Sapi_Ptcch: - // FIXME - default: - break; - } - - return rc; -} - -static void get_meas(struct pcu_l1_meas *meas, const GsmL1_MeasParam_t *l1_meas) -{ - meas->rssi = (int8_t) (l1_meas->fRssi); - meas->have_rssi = 1; - meas->ber = (uint8_t) (l1_meas->fBer * 100); - meas->have_ber = 1; - meas->bto = (int16_t) (l1_meas->i16BurstTiming); - meas->have_bto = 1; - meas->link_qual = (int16_t) (l1_meas->fLinkQuality); - meas->have_link_qual = 1; -} - -static int handle_ph_data_ind(struct femtol1_hdl *fl1h, - GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg) -{ - int rc = 0; - struct pcu_l1_meas meas = {0}; - - DEBUGP(DL1IF, "Rx PH-DATA.ind %s (hL2 %08x): %s\n", - get_value_string(femtobts_l1sapi_names, data_ind->sapi), - data_ind->hLayer2, - osmo_hexdump(data_ind->msgUnitParam.u8Buffer, - data_ind->msgUnitParam.u8Size)); - - pcu_rx_block_time(data_ind->u16Arfcn, data_ind->u32Fn, data_ind->u8Tn); - - /* - * TODO: Add proper bad frame handling here. This could be used - * to switch the used CS. Avoid a crash with the PCU right now - * feed "0 - 1" amount of data. - */ - if (data_ind->msgUnitParam.u8Size == 0) - return -1; - - gsmtap_send(fl1h->gsmtap, data_ind->u16Arfcn | GSMTAP_ARFCN_F_UPLINK, - data_ind->u8Tn, GSMTAP_CHANNEL_PACCH, 0, - data_ind->u32Fn, 0, 0, data_ind->msgUnitParam.u8Buffer+1, - data_ind->msgUnitParam.u8Size-1); - - get_meas(&meas, &data_ind->measParam); - - switch (data_ind->sapi) { - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - /* drop incomplete UL block */ - if (data_ind->msgUnitParam.u8Buffer[0] - != GsmL1_PdtchPlType_Full) - break; - /* PDTCH / PACCH frame handling */ - pcu_rx_data_ind_pdtch((long)fl1h->priv, data_ind->u8Tn, - data_ind->msgUnitParam.u8Buffer + 1, - data_ind->msgUnitParam.u8Size - 1, - data_ind->u32Fn, - &meas); - break; - case GsmL1_Sapi_Ptcch: - // FIXME - break; - default: - LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n", - get_value_string(femtobts_l1sapi_names, data_ind->sapi)); - break; - } - - return rc; -} - -#define MIN_QUAL_RACH 5.0f - -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 - - return 0; -} - - -/* handle any random indication from the L1 */ -int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg) -{ - GsmL1_Prim_t *l1p = msgb_l1prim(msg); - int rc = 0; - - LOGP(DL1IF, LOGL_DEBUG, "Rx L1 prim %s on queue %d\n", - get_value_string(femtobts_l1prim_names, l1p->id), wq); - - switch (l1p->id) { -#if 0 - case GsmL1_PrimId_MphTimeInd: - rc = handle_mph_time_ind(fl1h, &l1p->u.mphTimeInd); - break; - case GsmL1_PrimId_MphSyncInd: - break; - case GsmL1_PrimId_PhConnectInd: - break; -#endif - case GsmL1_PrimId_PhReadyToSendInd: - rc = handle_ph_readytosend_ind(fl1h, &l1p->u.phReadyToSendInd); - break; - case GsmL1_PrimId_PhDataInd: - rc = handle_ph_data_ind(fl1h, &l1p->u.phDataInd, msg); - break; - case GsmL1_PrimId_PhRaInd: - rc = handle_ph_ra_ind(fl1h, &l1p->u.phRaInd); - break; - default: - break; - } - - msgb_free(msg); - - return rc; -} - -int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - return -ENOTSUP; -} - -/* send packet data request to L1 */ -int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, - uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) -{ - struct femtol1_hdl *fl1h = obj; - struct msgb *msg; - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - struct gsm_time g_time; - - gsm_fn2gsmtime(&g_time, fn); - - DEBUGP(DL1IF, "TX packet data %02u/%02u/%02u is_ptcch=%d ts=%d " - "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, - g_time.t3, is_ptcch, ts, block_nr, arfcn, len); - - msg = l1p_msgb_alloc(); - l1p = msgb_l1prim(msg); - l1p->id = GsmL1_PrimId_PhDataReq; - data_req = &l1p->u.phDataReq; - data_req->hLayer1 = fl1h->hLayer1; - data_req->sapi = (is_ptcch) ? GsmL1_Sapi_Ptcch : GsmL1_Sapi_Pdtch; - data_req->subCh = GsmL1_SubCh_NA; - data_req->u8BlockNbr = block_nr; - data_req->u8Tn = ts; - data_req->u32Fn = fn; - msu_param = &data_req->msgUnitParam; - msu_param->u8Size = len; - memcpy(msu_param->u8Buffer, data, len); - - gsmtap_send(fl1h->gsmtap, arfcn, data_req->u8Tn, GSMTAP_CHANNEL_PACCH, - 0, data_req->u32Fn, 0, 0, - data_req->msgUnitParam.u8Buffer, - data_req->msgUnitParam.u8Size); - - - /* transmit */ - if (osmo_wqueue_enqueue(&fl1h->write_q[MQ_PDTCH_WRITE], msg) != 0) { - LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); - msgb_free(msg); - } - - return 0; -} - -void *l1if_open_pdch(void *priv, uint32_t hlayer1) -{ - struct femtol1_hdl *fl1h; - int rc; - - fl1h = talloc_zero(tall_pcu_ctx, struct femtol1_hdl); - if (!fl1h) - return NULL; - - fl1h->hLayer1 = hlayer1; - fl1h->priv = priv; - fl1h->clk_cal = 0; - /* default clock source: OCXO */ - fl1h->clk_src = SuperFemto_ClkSrcId_Ocxo; - - rc = l1if_transport_open(MQ_PDTCH_WRITE, fl1h); - if (rc < 0) { - talloc_free(fl1h); - return NULL; - } - - fl1h->gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 1); - if (fl1h->gsmtap) - gsmtap_source_add_sink(fl1h->gsmtap); - - return fl1h; -} - -int l1if_close_pdch(void *obj) -{ - struct femtol1_hdl *fl1h = obj; - if (fl1h) - l1if_transport_close(MQ_PDTCH_WRITE, fl1h); - talloc_free(fl1h); - return 0; -} - diff --git a/src/sysmo_l1_if.h b/src/sysmo_l1_if.h deleted file mode 100644 index 6b50d4e..0000000 --- a/src/sysmo_l1_if.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _SYSMO_L1_IF_H -#define _SYSMO_L1_IF_H - -#include -#include -#include -#include -#include "femtobts.h" - -enum { - MQ_SYS_READ, - MQ_L1_READ, -#ifndef HW_SYSMOBTS_V1 - MQ_TCH_READ, - MQ_PDTCH_READ, -#endif - _NUM_MQ_READ -}; - -enum { - MQ_SYS_WRITE, - MQ_L1_WRITE, -#ifndef HW_SYSMOBTS_V1 - MQ_TCH_WRITE, - MQ_PDTCH_WRITE, -#endif - _NUM_MQ_WRITE -}; - -struct femtol1_hdl { - struct gsm_time gsm_time; - uint32_t hLayer1; /* handle to the L1 instance in the DSP */ - uint32_t dsp_trace_f; - int clk_cal; - uint8_t clk_src; - struct llist_head wlc_list; - - struct gsmtap_inst *gsmtap; - uint32_t gsmtap_sapi_mask; - - void *priv; /* user reference */ - - struct osmo_timer_list alive_timer; - unsigned int alive_prim_cnt; - - struct osmo_fd read_ofd[_NUM_MQ_READ]; /* osmo file descriptors */ - struct osmo_wqueue write_q[_NUM_MQ_WRITE]; - - struct { - uint8_t dsp_version[3]; - uint8_t fpga_version[3]; - uint32_t band_support; /* bitmask of GSM_BAND_* */ - } hw_info; -}; - -#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) -#define msgb_sysprim(msg) ((SuperFemto_Prim_t *)(msg)->l1h) - -typedef int l1if_compl_cb(struct msgb *l1_msg, void *data); - -/* send a request primitive to the L1 and schedule completion call-back */ -int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg, - int is_system_prim, l1if_compl_cb *cb, void *data); - -int l1if_reset(struct femtol1_hdl *hdl); -int l1if_activate_rf(struct femtol1_hdl *hdl, int on); -int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags); -int l1if_set_txpower(struct femtol1_hdl *fl1h, float tx_power); - -struct msgb *l1p_msgb_alloc(void); -struct msgb *sysp_msgb_alloc(void); - -uint32_t l1if_lchan_to_hLayer2(struct gsm_lchan *lchan); -struct gsm_lchan *l1if_hLayer2_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2); - -int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg); -int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg); - -/* tch.c */ -int l1if_tch_rx(struct gsm_lchan *lchan, 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); - -/* - * The implementation of these functions is selected by either compiling and - * linking sysmo_l1_hw.c or sysmo_l1_fwd.c - */ -int l1if_transport_open(int q, struct femtol1_hdl *hdl); -int l1if_transport_close(int q, struct femtol1_hdl *hdl); - -#endif /* _SYSMO_L1_IF_H */ -- 2.5.0 From holger at freyther.de Tue Jan 26 15:27:54 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 26 Jan 2016 16:27:54 +0100 Subject: [PATCH 2/2] Restructure sources In-Reply-To: <1453821744-16428-2-git-send-email-suraev@alumni.ntnu.no> References: <1453821744-16428-1-git-send-email-suraev@alumni.ntnu.no> <1453821744-16428-2-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 26 Jan 2016, at 16:22, suraev at alumni.ntnu.no wrote: > > From: Max > > Move hardware-spicefic files into subdirectory similar to the way it's > done in OsmoBTS to make adding more hardware support easier. > Make DSP access option name generic. typo in specific, please send with -M to detect renames. Do not mix changes. We have nothing to hide here so please do not mix a huge rename with a change of the defines. thanks holger From jerlbeck at sysmocom.de Tue Jan 26 16:25:16 2016 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 26 Jan 2016 17:25:16 +0100 Subject: const question In-Reply-To: <20160126140145.GA10261@dub6> References: <20160126140145.GA10261@dub6> Message-ID: <56A79DEC.4000609@sysmocom.de> Hi, On 26.01.2016 15:01, Neels Hofmeyr wrote: > my attention was directed at the gprs_shift_v_fixed() function: > > int gprs_shift_v_fixed(uint8_t **data, size_t *data_len, > size_t len, uint8_t **value) > > It advances the *data pointer and returns a *value pointer. > So it could technically be consting much more aggressively. Yes it could if it was about plain information extraction. But these functions are used to get pointers to modifiable parts of the data for later patching. So ideally there were two functions, one like the above, and another with the signature gprs_shift_v_fixed_const(const uint8_t **data, size_t *data_len, size_t len, const uint8_t **value) Yes, C is not optimal for providing such a family of functions. > However, the compiler warnings confuse me. [...] > check.c: In function ?main?: > check.c:10:14: warning: passing argument 1 of ?func? from incompatible pointer type > func(&yy); > ^ > check.c:1:6: note: expected ?const int **? but argument is of type ?int **? > void func(const int **yyy) > > Changing yy to a pointer-to-const-int clears the warning: > > const int *yy = y; > func(&yy); [...] > > I just want to declare the underlying int data to be unchangeable by func(), > not caring whether the caller passes a const int or a mutable int buffer. > > Is the compiler merely nitpicking or am I getting something wrong > fundamentally? Perhaps http://stackoverflow.com/questions/28062095/pass-a-two-dimensional-array-to-a-function-of-constant-parameter sheds some light on that. Jacob -- - Jacob Erlbeck http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From suraev at alumni.ntnu.no Tue Jan 26 17:57:23 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Tue, 26 Jan 2016 18:57:23 +0100 Subject: [PATCH 4/5] Expand bitvec interface In-Reply-To: <160912F4-8E05-468D-B098-55210AB549A3@freyther.de> References: <1453477619-27336-1-git-send-email-suraev@alumni.ntnu.no> <1453477619-27336-4-git-send-email-suraev@alumni.ntnu.no> <28DA569B-B039-4896-9DDF-ACBF8DA124E8@freyther.de> <56A755DA.1010603@sysmocom.de> <160912F4-8E05-468D-B098-55210AB549A3@freyther.de> Message-ID: <56A7B383.1000703@alumni.ntnu.no> Attached v2 with style changed in places where it does not adversely affect readability. Feel free to amend commit to adjust copyright header as you see fit. cheers, Max. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Expand-bitvec-interface.patch Type: text/x-patch Size: 6064 bytes Desc: not available URL: From suraev at alumni.ntnu.no Tue Jan 26 18:27:12 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 19:27:12 +0100 Subject: [PATCH 2/3] Rename define for direct hw access In-Reply-To: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453832833-15763-3-git-send-email-suraev@alumni.ntnu.no> From: Max --- src/Makefile.am | 2 +- src/osmobts_sock.cpp | 2 +- src/pcu_l1_if.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6428bef..832c3b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) if ENABLE_SYSMODSP -AM_CPPFLAGS += -DENABLE_SYSMODSP +AM_CPPFLAGS += -DENABLE_DIRECT_PHY endif AM_CXXFLAGS = -Wall -ldl -pthread diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp index b42f042..21a404f 100644 --- a/src/osmobts_sock.cpp +++ b/src/osmobts_sock.cpp @@ -100,7 +100,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) /* disable all slots, kick all TBFs */ for (trx = 0; trx < 8; trx++) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if (bts->trx[trx].fl1h) { l1if_close_pdch(bts->trx[trx].fl1h); bts->trx[trx].fl1h = NULL; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 9d7dbee..a19b957 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -124,7 +124,7 @@ static int pcu_tx_data_req(uint8_t trx, uint8_t ts, uint8_t sapi, void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY struct gprs_rlcmac_bts *bts = bts_main_data(); if (bts->trx[trx].fl1h) @@ -430,7 +430,7 @@ bssgp_failed: bts->trx[trx].arfcn = info_ind->trx[trx].arfcn; if ((info_ind->flags & PCU_IF_FLAG_SYSMO) && info_ind->trx[trx].hlayer1) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY LOGP(DL1IF, LOGL_DEBUG, " TRX %d hlayer1=%x\n", trx, info_ind->trx[trx].hlayer1); if (!bts->trx[trx].fl1h) @@ -455,7 +455,7 @@ bssgp_failed: if ((info_ind->trx[trx].pdch_mask & (1 << ts))) { /* FIXME: activate dynamically at RLCMAC */ if (!pdch->is_enabled()) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if ((info_ind->flags & PCU_IF_FLAG_SYSMO)) l1if_connect_pdch( -- 2.5.0 From suraev at alumni.ntnu.no Tue Jan 26 18:27:10 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 19:27:10 +0100 Subject: [PATCH 0/3] Cleanup and restructure Message-ID: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> From: Max This small patchset enables future hardware support by restructuring sources and cleaning up few bits here and there. Max (3): Cleanup build Rename define for direct hw access Restructure sources .gitignore | 2 ++ configure.ac | 2 +- src/Makefile.am | 51 +++++++++++++++++++-------------- src/{ => osmo-bts-sysmo}/femtobts.c | 0 src/{ => osmo-bts-sysmo}/femtobts.h | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_fwd.c | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_hw.c | 4 +-- src/{ => osmo-bts-sysmo}/sysmo_l1_if.c | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_if.h | 0 src/osmobts_sock.cpp | 2 +- src/pcu_l1_if.cpp | 6 ++-- 11 files changed, 39 insertions(+), 28 deletions(-) rename src/{ => osmo-bts-sysmo}/femtobts.c (100%) rename src/{ => osmo-bts-sysmo}/femtobts.h (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_fwd.c (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_hw.c (97%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_if.c (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_if.h (100%) -- 2.5.0 From suraev at alumni.ntnu.no Tue Jan 26 18:27:11 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 19:27:11 +0100 Subject: [PATCH 1/3] Cleanup build In-Reply-To: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453832833-15763-2-git-send-email-suraev@alumni.ntnu.no> From: Max Ignore cross-compilation bild byproducts. Enable subdir-objects to increase compatibility with newer automake. --- .gitignore | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6cc9aa5..439f591 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ depcomp install-sh missing libtool +arm*linux*libtool +compile ltmain.sh core diff --git a/configure.ac b/configure.ac index 5274022..7a97954 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_INIT([osmo-pcu], m4_esyscmd([./git-version-gen .tarball-version]), [osmocom-net-gprs at lists.osmocom.org]) -AM_INIT_AUTOMAKE([dist-bzip2]) +AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects]) AC_CONFIG_TESTDIR(tests) dnl kernel style compile messages -- 2.5.0 From suraev at alumni.ntnu.no Tue Jan 26 18:27:13 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Tue, 26 Jan 2016 19:27:13 +0100 Subject: [PATCH 3/3] Restructure sources In-Reply-To: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453832833-15763-4-git-send-email-suraev@alumni.ntnu.no> From: Max Move hardware-spicefic files into subdirectory similar to the way it's done in OsmoBTS to make adding more hardware support easier. --- src/Makefile.am | 49 +++++++++++++++++++-------------- src/{ => osmo-bts-sysmo}/femtobts.c | 0 src/{ => osmo-bts-sysmo}/femtobts.h | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_fwd.c | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_hw.c | 4 +-- src/{ => osmo-bts-sysmo}/sysmo_l1_if.c | 0 src/{ => osmo-bts-sysmo}/sysmo_l1_if.h | 0 7 files changed, 31 insertions(+), 22 deletions(-) rename src/{ => osmo-bts-sysmo}/femtobts.c (100%) rename src/{ => osmo-bts-sysmo}/femtobts.h (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_fwd.c (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_hw.c (97%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_if.c (100%) rename src/{ => osmo-bts-sysmo}/sysmo_l1_if.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 832c3b0..3049744 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,11 +64,6 @@ bin_PROGRAMS = \ noinst_PROGRAMS = -if ENABLE_SYSMODSP -noinst_PROGRAMS += \ - osmo-pcu-remote -endif - noinst_HEADERS = \ gprs_debug.h \ csn1.h \ @@ -83,8 +78,6 @@ noinst_HEADERS = \ bitvector.h \ pcu_vty.h \ pcu_vty_functions.h \ - sysmo_l1_if.h \ - femtobts.h \ tbf.h \ bts.h \ poll_controller.h \ @@ -101,30 +94,46 @@ noinst_HEADERS = \ osmo_pcu_SOURCES = pcu_main.cpp if ENABLE_SYSMODSP -osmo_pcu_SOURCES += sysmo_l1_if.c \ - sysmo_l1_hw.c \ - femtobts.c - -osmo_pcu_remote_SOURCES = pcu_main.cpp \ - sysmo_l1_if.c \ - sysmo_l1_fwd.c \ - femtobts.c -endif +AM_CPPFLAGS += -I$(srcdir)/osmo-bts-sysmo -osmo_pcu_LDADD = \ +EXTRA_DIST = \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c \ + osmo-bts-sysmo/femtobts.h + +noinst_HEADERS += \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/femtobts.h + +noinst_PROGRAMS += \ + osmo-pcu-remote + +osmo_pcu_SOURCES += \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_SOURCES = \ + pcu_main.cpp \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_fwd.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) +endif -if ENABLE_SYSMODSP -osmo_pcu_remote_LDADD = \ +osmo_pcu_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) -endif #MOSTLYCLEANFILES += testSource testDestination diff --git a/src/femtobts.c b/src/osmo-bts-sysmo/femtobts.c similarity index 100% rename from src/femtobts.c rename to src/osmo-bts-sysmo/femtobts.c diff --git a/src/femtobts.h b/src/osmo-bts-sysmo/femtobts.h similarity index 100% rename from src/femtobts.h rename to src/osmo-bts-sysmo/femtobts.h diff --git a/src/sysmo_l1_fwd.c b/src/osmo-bts-sysmo/sysmo_l1_fwd.c similarity index 100% rename from src/sysmo_l1_fwd.c rename to src/osmo-bts-sysmo/sysmo_l1_fwd.c diff --git a/src/sysmo_l1_hw.c b/src/osmo-bts-sysmo/sysmo_l1_hw.c similarity index 97% rename from src/sysmo_l1_hw.c rename to src/osmo-bts-sysmo/sysmo_l1_hw.c index 8351d68..2c019be 100644 --- a/src/sysmo_l1_hw.c +++ b/src/osmo-bts-sysmo/sysmo_l1_hw.c @@ -59,8 +59,8 @@ #define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" #define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" -#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm" -#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp" +#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm1" //2 -- trx1 +#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp1" //2 #endif static const char *rd_devnames[] = { diff --git a/src/sysmo_l1_if.c b/src/osmo-bts-sysmo/sysmo_l1_if.c similarity index 100% rename from src/sysmo_l1_if.c rename to src/osmo-bts-sysmo/sysmo_l1_if.c diff --git a/src/sysmo_l1_if.h b/src/osmo-bts-sysmo/sysmo_l1_if.h similarity index 100% rename from src/sysmo_l1_if.h rename to src/osmo-bts-sysmo/sysmo_l1_if.h -- 2.5.0 From holger at freyther.de Tue Jan 26 20:24:56 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 26 Jan 2016 21:24:56 +0100 Subject: [PATCH 3/3] Restructure sources In-Reply-To: <1453832833-15763-4-git-send-email-suraev@alumni.ntnu.no> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> <1453832833-15763-4-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1D78176D-5EC3-463A-B6E7-9233F43729EC@freyther.de> > On 26 Jan 2016, at 19:27, suraev at alumni.ntnu.no wrote: Dear Max, > #define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" > #define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" > -#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm" > -#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp" > +#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm1" //2 -- trx1 > +#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp1" //2 as this is about restructuring the sourcecode I would have not expected such a modification. Does this file exist on a single trx system? holger From nhofmeyr at sysmocom.de Wed Jan 27 08:23:19 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Wed, 27 Jan 2016 09:23:19 +0100 Subject: const question In-Reply-To: <56A79DEC.4000609@sysmocom.de> References: <20160126140145.GA10261@dub6> <56A79DEC.4000609@sysmocom.de> Message-ID: <20160127082319.GB1185@dub6> On Tue, Jan 26, 2016 at 05:25:16PM +0100, Jacob Erlbeck wrote: > Yes, C is not optimal for providing such a family of functions. Sheesh. I'm kinda disappointed now. It seems C++ has the same kludge, though I thought I remembered to have used as const implicitly before... maybe some old memory from Java times long passed... > Perhaps > http://stackoverflow.com/questions/28062095/pass-a-two-dimensional-array-to-a-function-of-constant-parameter > sheds some light on that. Thanks for the link! That one evaded me while searching. And thanks for nothing, C *sulk* ;) ~Neels -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From suraev at alumni.ntnu.no Wed Jan 27 09:40:23 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Wed, 27 Jan 2016 10:40:23 +0100 Subject: [PATCH 3/3] Restructure sources In-Reply-To: <1D78176D-5EC3-463A-B6E7-9233F43729EC@freyther.de> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> <1453832833-15763-4-git-send-email-suraev@alumni.ntnu.no> <1D78176D-5EC3-463A-B6E7-9233F43729EC@freyther.de> Message-ID: <56A89087.1020701@alumni.ntnu.no> Oops, my bad - I've accidentally committed part of another development work which does not belong in here. Please disregard this particular change. I've double-checked all the patches and the rest seems fine - only those defines were mistakenly committed. cheers, Max. From nhofmeyr at sysmocom.de Wed Jan 27 15:58:17 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Wed, 27 Jan 2016 16:58:17 +0100 Subject: Status Report on Osmocom's 3G Support Message-ID: <20160127155817.GD1549@dub6> Hi list, it's time for a summary of our progress in the 3G realm. Just this minute, I have posted a blog entry that describes our aim as well as the current development status in abundant detail. At your convenience, see for yourself and visit: https://openbsc.osmocom.org/trac/blog/3G_2016_01 Happy hacking! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From suraev at alumni.ntnu.no Wed Jan 27 17:55:21 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Wed, 27 Jan 2016 18:55:21 +0100 Subject: [PATCH] Fix error introduced in a15f05f1b43d8e85d9a3f72a0a Message-ID: <1453917321-31242-1-git-send-email-suraev@alumni.ntnu.no> From: Max Fix error creeped in while porting code from cpp refs. Add test case for code in question. Expand documentatin to clarify function use. --- src/bitvec.c | 24 +++++++++++++++++++----- tests/bitvec/bitvec_test.c | 15 +++++++++++++++ tests/bitvec/bitvec_test.ok | 12 ++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/bitvec.c b/src/bitvec.c index f9341b7..b88afa6 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -138,6 +138,7 @@ unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n) * \param[in] bv bit vector on which to operate * \param[in] bitnr number of bit to be set * \param[in] bit value to which the bit is to be set + * \returns 0 on success, negative value on error */ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr, enum bit_value bit) @@ -163,6 +164,7 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr, /*! \brief set the next bit inside a bitvec * \param[in] bv bit vector to be used * \param[in] bit value of the bit to be set + * \returns 0 on success, negative value on error */ int bitvec_set_bit(struct bitvec *bv, enum bit_value bit) { @@ -390,11 +392,18 @@ int bitvec_unhex(struct bitvec *bv, const char *src) if (sscanf(src + i, "%1x", &val) < 1) { return 1; } - bitvec_write_field(bv, write_index,val, 4); + bitvec_write_field(bv, write_index, val, 4); + write_index += 4; } return 0; } +/*! \brief read part of the vector + * \param[in] bv The boolean vector to work on + * \param[in] read_index Where reading supposed to start in the vector + * \param[in] len How many bits to read from vector + * \returns read bits or negative value on error + */ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len) { unsigned int i; @@ -409,11 +418,16 @@ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned ui |= ((uint64_t)1 << (len - i - 1)); bv->cur_bit++; } - read_index += len; + return ui; } - +/*! \brief write into the vector + * \param[in] bv The boolean vector to work on + * \param[in] write_index Where writing supposed to start in the vector + * \param[in] len How many bits to write + * \returns next write index or negative value on error + */ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len) { unsigned int i; @@ -427,8 +441,8 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val if (rc) return rc; } - write_index += len; - return 0; + + return write_index + len; } /*! @} */ diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c index 624e334..dde8448 100644 --- a/tests/bitvec/bitvec_test.c +++ b/tests/bitvec/bitvec_test.c @@ -55,8 +55,23 @@ static void test_byte_ops() printf("=== end %s ===\n", __func__); } +static void test_unhex(char *hex) +{ + struct bitvec b; + uint8_t d[64] = {0}; + b.data = d; + b.data_len = sizeof(d); + b.cur_bit = 0; + printf("%d -=>\n", bitvec_unhex(&b, hex)); + printf("%s\n%s\n", osmo_hexdump_nospc(d, 64), osmo_hexdump_nospc(hex, 23)); +} + int main(int argc, char **argv) { test_byte_ops(); + test_unhex("48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b"); + test_unhex("47240c00400000000000000079eb2ac9402b2b2b2b2b2b"); + test_unhex("47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b"); + test_unhex("DEADFACE000000000000000000000000000000BEEFFEED"); return 0; } diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok index 1f329af..17e8fd2 100644 --- a/tests/bitvec/bitvec_test.ok +++ b/tests/bitvec/bitvec_test.ok @@ -1,2 +1,14 @@ === start test_byte_ops === === end test_byte_ops === +1 -=> +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 2.5.0 From holger at freyther.de Wed Jan 27 19:49:05 2016 From: holger at freyther.de (Holger Freyther) Date: Wed, 27 Jan 2016 20:49:05 +0100 Subject: [PATCH] Fix error introduced in a15f05f1b43d8e85d9a3f72a0a In-Reply-To: <1453917321-31242-1-git-send-email-suraev@alumni.ntnu.no> References: <1453917321-31242-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <7300BFB8-98A0-4D93-9216-35CC740380FA@freyther.de> > On 27 Jan 2016, at 18:55, suraev at alumni.ntnu.no wrote: > > From: Max > > Fix error creeped in while porting code from cpp refs. > Add test case for code in question. > Expand documentatin to clarify function use. Be more specific here. Which routines were impacted? Sure all calls to bitvec_write_field. Why do you decide to not make this variable an in+out variable and instead need to know how many spaces it advanced? Have you checked the other code that was converted? > +static void test_unhex(char *hex) > +{ > + struct bitvec b; > + uint8_t d[64] = {0}; > + b.data = d; > + b.data_len = sizeof(d); > + b.cur_bit = 0; > + printf("%d -=>\n", bitvec_unhex(&b, hex)); > + printf("%s\n%s\n", osmo_hexdump_nospc(d, 64), osmo_hexdump_nospc(hex, 23)); Extend the test to see what happens if you unhex more than d can hold? Instead of dumping up to 64bytes can you see how many bytes are filled? int bitvec_write_field(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len) { unsigned int i; int rc; bv->cur_bit = write_index; for (i = 0; i < len; i++) { int bit = 0; if (val & ((uint64_t)1 << (len - i - 1))) bit = 1; rc = bitvec_set_bit(bv, (bit_value)bit); if (rc) return rc; } write_index += len; return 0; } so if you take the "unsigned&" and make it a plain variable then the write_index += len at the end mkes no sense and can be removed? From suraev at alumni.ntnu.no Thu Jan 28 09:04:52 2016 From: suraev at alumni.ntnu.no (=?UTF-8?B?TWF4ICjimK0p?=) Date: Thu, 28 Jan 2016 10:04:52 +0100 Subject: [PATCH] Fix error introduced in a15f05f1b43d8e85d9a3f72a0a In-Reply-To: <7300BFB8-98A0-4D93-9216-35CC740380FA@freyther.de> References: <1453917321-31242-1-git-send-email-suraev@alumni.ntnu.no> <7300BFB8-98A0-4D93-9216-35CC740380FA@freyther.de> Message-ID: <56A9D9B4.5070300@alumni.ntnu.no> 27.01.2016 20:49, Holger Freyther ?????: > > > Be more specific here. Which routines were impacted? Sure > all calls to bitvec_write_field. bitvec_unhex() is the only consumer in libosmocore for bitvec_write_field() so far > Why do you decide to not > make this variable an in+out variable and instead need to > know how many spaces it advanced? I've tested that approach as well but it makes code much harder to read without providing any real benefits. > Have you checked the other code that was converted? > Yes, the only potentially problematic functions are bitvec_*_field() > Extend the test to see what happens if you unhex more than d > can hold? Will do. > Instead of dumping up to 64bytes can you see how many bytes are > filled? > The functions for that are part of another patch currently under review as well. I did not wanted to reimplement them just for one test-case. I can extend this once it's merged. > > so if you take the "unsigned&" and make it a plain variable then the > write_index += len at the end mkes no sense and can be removed? > Yes. In the patch in question I instead return write_index+len to make it easier for caller. cheers, Max. From nhofmeyr at sysmocom.de Thu Jan 28 11:17:34 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Thu, 28 Jan 2016 12:17:34 +0100 Subject: IuPS and IuCS branches Message-ID: <20160128111734.GA1755@dub6> Hey Daniel, we are working on our separate branches in openbsc: daniel/gprs-iu and neels/cscn. Merging them will be nontrivial, at least because I have moved gprs/sgsn_iu.c to new libiu/iu.c and include/.../iu.h. That's because some of the stuff there is useful outside of the gprs scope. Otherwise I've not changed the code much, you have at least a little, so before we potentially further complicate the changes, we may benefit from consolidating our branches, sooner rather than later... Though my cscn code doesn't do anything useful yet, it is in a separate new subdir, so merging it to master wouldn't break anything. Merging both our stuffs to master is what I would suggest. If you merge to master first I volunteer to rebase mine and take on the hard half of the merge myself. OTOH, if I'm faster ... ;) (More precisely, I'll bump this in at most two weeks, so plz go for it.) Opinions/strategies welcome! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From suraev at alumni.ntnu.no Thu Jan 28 11:28:28 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 28 Jan 2016 12:28:28 +0100 Subject: [PATCH 1/4] Improve code style and readability Message-ID: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> From: Max --- src/bitvec.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/bitvec.c b/src/bitvec.c index f9341b7..7254674 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -383,14 +383,12 @@ unsigned int bitvec_unpack(struct bitvec *bv, const uint8_t *buffer) int bitvec_unhex(struct bitvec *bv, const char *src) { - unsigned val; - unsigned write_index = 0; - unsigned digits = bv->data_len * 2; - for (unsigned i = 0; i < digits; i++) { - if (sscanf(src + i, "%1x", &val) < 1) { + unsigned val, i, write_index = 0; + for (i = 0; i < bv->data_len * 2; i++) { + if (sscanf(src + i, "%1x", &val) < 1) return 1; - } - bitvec_write_field(bv, write_index,val, 4); + + bitvec_write_field(bv, write_index, val, 4); } return 0; } -- 2.5.0 From suraev at alumni.ntnu.no Thu Jan 28 11:28:29 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 28 Jan 2016 12:28:29 +0100 Subject: [PATCH 2/4] Fix error introduced in a15f05f1b43d8e85d9a3f72a0a In-Reply-To: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> References: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453980511-1787-2-git-send-email-suraev@alumni.ntnu.no> From: Max The code in bitvec_*_field was incorrectly ported from C++. This also affected bitvec_unhex which uses it. --- src/bitvec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bitvec.c b/src/bitvec.c index 7254674..407dfc8 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -389,6 +389,7 @@ int bitvec_unhex(struct bitvec *bv, const char *src) return 1; bitvec_write_field(bv, write_index, val, 4); + write_index += 4; } return 0; } @@ -407,7 +408,7 @@ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned ui |= ((uint64_t)1 << (len - i - 1)); bv->cur_bit++; } - read_index += len; + return ui; } @@ -425,8 +426,8 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val if (rc) return rc; } - write_index += len; - return 0; + + return write_index + len; } /*! @} */ -- 2.5.0 From suraev at alumni.ntnu.no Thu Jan 28 11:28:30 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 28 Jan 2016 12:28:30 +0100 Subject: [PATCH 3/4] Add doxygen comments to clarify function use In-Reply-To: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> References: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453980511-1787-3-git-send-email-suraev@alumni.ntnu.no> From: Max --- src/bitvec.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/bitvec.c b/src/bitvec.c index 407dfc8..2221142 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -138,6 +138,7 @@ unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n) * \param[in] bv bit vector on which to operate * \param[in] bitnr number of bit to be set * \param[in] bit value to which the bit is to be set + * \returns 0 on success, negative value on error */ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr, enum bit_value bit) @@ -163,6 +164,7 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr, /*! \brief set the next bit inside a bitvec * \param[in] bv bit vector to be used * \param[in] bit value of the bit to be set + * \returns 0 on success, negative value on error */ int bitvec_set_bit(struct bitvec *bv, enum bit_value bit) { @@ -394,6 +396,12 @@ int bitvec_unhex(struct bitvec *bv, const char *src) return 0; } +/*! \brief read part of the vector + * \param[in] bv The boolean vector to work on + * \param[in] read_index Where reading supposed to start in the vector + * \param[in] len How many bits to read from vector + * \returns read bits or negative value on error + */ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len) { unsigned int i; @@ -412,7 +420,12 @@ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned return ui; } - +/*! \brief write into the vector + * \param[in] bv The boolean vector to work on + * \param[in] write_index Where writing supposed to start in the vector + * \param[in] len How many bits to write + * \returns next write index or negative value on error + */ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len) { unsigned int i; -- 2.5.0 From suraev at alumni.ntnu.no Thu Jan 28 11:28:31 2016 From: suraev at alumni.ntnu.no (suraev at alumni.ntnu.no) Date: Thu, 28 Jan 2016 12:28:31 +0100 Subject: [PATCH 4/4] Add tests for bitvec_unhex function In-Reply-To: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> References: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> Message-ID: <1453980511-1787-4-git-send-email-suraev@alumni.ntnu.no> From: Max --- tests/bitvec/bitvec_test.c | 16 ++++++++++++++++ tests/bitvec/bitvec_test.ok | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c index 624e334..789df75 100644 --- a/tests/bitvec/bitvec_test.c +++ b/tests/bitvec/bitvec_test.c @@ -55,8 +55,24 @@ static void test_byte_ops() printf("=== end %s ===\n", __func__); } +static void test_unhex(const char *hex) +{ + struct bitvec b; + uint8_t d[64] = {0}; + b.data = d; + b.data_len = sizeof(d); + b.cur_bit = 0; + printf("%d -=>\n", bitvec_unhex(&b, hex)); + printf("%s\n%s\n", osmo_hexdump_nospc(d, 64), osmo_hexdump_nospc((const unsigned char *)hex, 23)); +} + int main(int argc, char **argv) { test_byte_ops(); + test_unhex("48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b"); + test_unhex("47240c00400000000000000079eb2ac9402b2b2b2b2b2b"); + test_unhex("47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b"); + test_unhex("DEADFACE000000000000000000000000000000BEEFFEED"); + test_unhex("FFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); return 0; } diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok index 1f329af..8d944bc 100644 --- a/tests/bitvec/bitvec_test.ok +++ b/tests/bitvec/bitvec_test.ok @@ -1,2 +1,17 @@ === start test_byte_ops === === end test_byte_ops === +1 -=> +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1 -=> +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0 -=> +fffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +fffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -- 2.5.0 From nhofmeyr at sysmocom.de Thu Jan 28 12:08:43 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Thu, 28 Jan 2016 13:08:43 +0100 Subject: cscn copyright question Message-ID: <20160128120843.GB1755@dub6> Is this a proper way to copyright OsmoCSCN? I'm trying to mention both the facts that it's something new as well as that it is based on a copy-paste of OsmoNITB: /* (C) 2016 by sysmocom s.f.m.c. GmbH * All Rights Reserved * * Based on OsmoNITB: * (C) 2008-2010 by Harald Welte * (C) 2009-2012 by Holger Hans Peter Freyther * All Rights Reserved [...] Thanks! ~Neels -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From nhofmeyr at sysmocom.de Thu Jan 28 13:32:39 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Thu, 28 Jan 2016 14:32:39 +0100 Subject: FIXME: TODO: do better Message-ID: <20160128133239.GD1755@dub6> Would anyone like to prevent this commit from reaching master? ;) Thanks! ~Neels commit 76af8ad075e7857983ef102f80440ee716958482 Author: Neels Hofmeyr Date: Thu Jan 28 14:26:05 2016 +0100 add fixme comment for todo comment :/ diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index b4facff..4bea699 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -48,7 +48,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg gsm0408_new_conn(conn); gsm0408_dispatch(conn, msg); - /* TODO: do better */ + /* TODO: do better */ /* FIXME: do the TODO comment better in the first place! */ if (conn->silent_call) return BSC_API_CONN_POL_ACCEPT; if (conn->loc_operation || conn->sec_operation || conn->anch_operation) -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From holger at freyther.de Sat Jan 30 09:01:52 2016 From: holger at freyther.de (Holger Freyther) Date: Sat, 30 Jan 2016 10:01:52 +0100 Subject: [PATCH 1/3] Cleanup build In-Reply-To: <1453832833-15763-2-git-send-email-suraev@alumni.ntnu.no> References: <1453832833-15763-1-git-send-email-suraev@alumni.ntnu.no> <1453832833-15763-2-git-send-email-suraev@alumni.ntnu.no> Message-ID: > On 26 Jan 2016, at 19:27, suraev at alumni.ntnu.no wrote: > > > libtool > +arm*linux*libtool *libtool then? > -AM_INIT_AUTOMAKE([dist-bzip2]) > +AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects]) have you tried make distcheck? From holger at freyther.de Sat Jan 30 09:09:39 2016 From: holger at freyther.de (Holger Freyther) Date: Sat, 30 Jan 2016 10:09:39 +0100 Subject: [PATCH 4/4] Add tests for bitvec_unhex function In-Reply-To: <1453980511-1787-4-git-send-email-suraev@alumni.ntnu.no> References: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> <1453980511-1787-4-git-send-email-suraev@alumni.ntnu.no> Message-ID: <5127DF28-B8FA-44A5-B9A5-BA67DBEC70C0@freyther.de> > On 28 Jan 2016, at 12:28, suraev at alumni.ntnu.no wrote: > > From: Max Dear Max, one can put fix and testcase into the same commit, if you decide to split it up then first commit the testcase with an expected failure and then when you fix things, fix the test result. This will show/track the change in behavior. In my initial review I had asked for a stronger post condition and I still think this applies to the test. I see we have one truncation test but I don't see a test that checks how many bits have been taken from the hexstring. > > --- > tests/bitvec/bitvec_test.c | 16 ++++++++++++++++ > tests/bitvec/bitvec_test.ok | 15 +++++++++++++++ > 2 files changed, 31 insertions(+) > > diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c > index 624e334..789df75 100644 > --- a/tests/bitvec/bitvec_test.c > +++ b/tests/bitvec/bitvec_test.c > @@ -55,8 +55,24 @@ static void test_byte_ops() > printf("=== end %s ===\n", __func__); > } > > +static void test_unhex(const char *hex) > +{ > + struct bitvec b; > + uint8_t d[64] = {0}; > + b.data = d; > + b.data_len = sizeof(d); > + b.cur_bit = 0; > + printf("%d -=>\n", bitvec_unhex(&b, hex)); > + printf("%s\n%s\n", osmo_hexdump_nospc(d, 64), osmo_hexdump_nospc((const unsigned char *)hex, 23)); > +} > + > int main(int argc, char **argv) > { > test_byte_ops(); > + test_unhex("48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b"); > + test_unhex("47240c00400000000000000079eb2ac9402b2b2b2b2b2b"); > + test_unhex("47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b"); > + test_unhex("DEADFACE000000000000000000000000000000BEEFFEED"); > + test_unhex("FFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); > return 0; > } > diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok > index 1f329af..8d944bc 100644 > --- a/tests/bitvec/bitvec_test.ok > +++ b/tests/bitvec/bitvec_test.ok > @@ -1,2 +1,17 @@ > === start test_byte_ops === > === end test_byte_ops === > +1 -=> > +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +1 -=> > +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +47240c00400000000000000079eb2ac9402b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +1 -=> > +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +1 -=> > +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +deadface000000000000000000000000000000beeffeed0000000000000000000000000000000000000000000000000000000000000000000000000000000000 > +0 -=> > +fffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > +fffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > -- > 2.5.0 > From holger at freyther.de Sat Jan 30 09:35:00 2016 From: holger at freyther.de (Holger Freyther) Date: Sat, 30 Jan 2016 10:35:00 +0100 Subject: [PATCH 2/4] Fix error introduced in a15f05f1b43d8e85d9a3f72a0a In-Reply-To: <1453980511-1787-2-git-send-email-suraev@alumni.ntnu.no> References: <1453980511-1787-1-git-send-email-suraev@alumni.ntnu.no> <1453980511-1787-2-git-send-email-suraev@alumni.ntnu.no> Message-ID: <7F34ED2E-19EB-4E3E-A9F1-43AB4EE89FBB@freyther.de> > On 28 Jan 2016, at 12:28, suraev at alumni.ntnu.no wrote: > Dear Max, > The code in bitvec_*_field was incorrectly ported from C++. and this is why a good commit message is so important. I assumed you had simply copied the code from the PCU to libosmocore. I had no indication that you had to change the semantic as part of C++ -> C. It would have been important to write the thoughts of how you dealt with the C++ reference and converted it to C. After looking at the PCU I think the change from reference to pass by value is a dangerous decision. bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); The code will silently continue to compile and this is why I think the signature of bitvec_write_field and bitvec_read_field needs to be a pointer to not have a huge mess with the osmo_pcu code. holger From omar.ramadan at berkeley.edu Sun Jan 31 22:09:51 2016 From: omar.ramadan at berkeley.edu (OMAR RAMADAN) Date: Sun, 31 Jan 2016 14:09:51 -0800 Subject: LCR segfault on SIP invite In-Reply-To: <20160118152936.GL17432@nataraja> References: <20160118152936.GL17432@nataraja> Message-ID: So it turns out gcc 4.8 optimizes too aggressively when compiling sofia-sip for LCR. Another symptom of this is that message payloads are missing. Solution is to compile with "-fno-aggressive-loop-optimizations" On Mon, Jan 18, 2016 at 7:29 AM, Harald Welte wrote: > Hi Omar, > > On Fri, Jan 15, 2016 at 11:50:47AM -0800, OMAR RAMADAN wrote: > > I'm using LCR as a GSM <-> SIP interface and I've been trying to figure > out > > why MO calls result in a segfault. I am running openbsc on cdc548cb and > LCR > > on c14326641a built and run on an ubuntu 14.04 64bit. > > As this sounds like an LCR issue, and not an OpenBSC one,please consider > posting this to the isdn4linux mailing list, as indicated at the bottom > of the page http://www.linux-call-router.de/ > > -- > - Harald Welte > http://laforge.gnumonks.org/ > > ============================================================================ > "Privacy in residential applications is a desirable marketing option." > (ETSI EN 300 175-7 Ch. > A6) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From yasith123 at hotmail.com Fri Jan 15 17:31:50 2016 From: yasith123 at hotmail.com (yasith Guette Oliveros) Date: Fri, 15 Jan 2016 17:31:50 -0000 Subject: Help Bts3900B Message-ID: Hi buy a bts3900B on Ebay. I have a project similar to yours. I want to know if it was possible to open the connection with BSC. I also want my users to browse internet through my mobile network. I appreciate your help in my project. -------------- next part -------------- An HTML attachment was scrubbed... URL: