From holger at freyther.de Tue Aug 5 13:18:20 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 5 Aug 2014 15:18:20 +0200 Subject: OsmoSGSN [PATCH], Network Service In-Reply-To: References: <20140517115033.GC14533@nataraja> Message-ID: <20140805131820.GA22863@xiaoyu.lan> On Fri, May 23, 2014 at 11:44:40AM +0200, Michal Grzn?r wrote: Hi, > Hi, I am sorry for my previous bad post format. There are the right diff > files. > And the problem was as I said in Imsi attach procedure new TLLI == new > allocated P-tmsi, and there was a problem that the function gprs_tmsi2tlli() > function there was not called and so I had to mask the upper bits in > function where the p-tmsi is allocated, there is also a pcap trace where > you can see it. sorry for the late reply. The issue is that your MS does not convert the P-TMSI to a Local-TLLI. On the other hand Jacob has pointed me to some documentation of a measurement equipment manufacturer that states that the local bits/highest two bits of the ptmsi should be set. > > > restart: > > > +++ ptmsi = rand() | 0xc0000000; /*because of GPRS IMSI we will carry a patch like this. From dwillmann at sysmocom.de Thu Aug 7 14:20:06 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Thu, 7 Aug 2014 16:20:06 +0200 Subject: [osmo-pcu 1/5] bts: Ensure tbf direction with OSMO_ASSERT() In-Reply-To: <20140717064624.GA18946@xiaoyu.lan> References: <2207c5e4ef0565ab782196a80cc45dcc458938e4.1405530272.git.daniel@totalueberwachung.de> <20140717064624.GA18946@xiaoyu.lan> Message-ID: <20140807142006.GA15285@adrastea.totalueberwachung.de> Hi, On Thu, 2014-07-17 at 08:46, Holger Hans Peter Freyther wrote: > On Wed, Jul 16, 2014 at 07:04:28PM +0200, Daniel Willmann wrote: > as we have to move forward I will merge it. One comment in regard to > the approach taken here. > > > +gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi, > > + enum gprs_rlcmac_tbf_direction dir) > > { > > gprs_rlcmac_tbf *tbf; > > > > llist_for_each_entry(tbf, tbf_list, list) { > > + OSMO_ASSERT(tbf->direction == dir); > > > + return tbf_from_list_by_tfi(&bts_data()->ul_tbfs, tfi, GPRS_RLCMAC_UL_TBF); > > + return tbf_from_list_by_tfi(&bts_data()->dl_tbfs, tfi, GPRS_RLCMAC_DL_TBF); > > assert it on _entry_ into the ul_tbfs and dl_tbfs. If we only have one > place where the list is manipulated we can easily pay the price on entry. This is obsolete now anyway as the functions that do llist_add explicitly allocate a DL/UL TBF. I have a patch that will remove the ASSERTs completely Regards, Daniel Willmann -- - Daniel Willmann http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Max.Suraev at fairwaves.co Wed Aug 6 11:04:01 2014 From: Max.Suraev at fairwaves.co (=?UTF-8?B?4piO?=) Date: Wed, 06 Aug 2014 13:04:01 +0200 Subject: [PATCH] Fix some packaging mistakes detected by lintian. In-Reply-To: <20140730064622.GU5744@xiaoyu.lan> References: <1406041637-14296-1-git-send-email-max.suraev@fairwaves.co> <20140730064622.GU5744@xiaoyu.lan> Message-ID: <53E20BA1.5030706@fairwaves.co> My bad - I'm using too much of a bleeding edge :) Put whatever works for your main build machine. 30.07.2014 08:46, Holger Hans Peter Freyther ?????: > On Tue, Jul 22, 2014 at 05:07:17PM +0200, Max Suraev wrote: > >> -Standards-Version: 3.8.4 >> +Standards-Version: 3.9.5 > > So on which distributions can we build packages then. Using the > latest version is all nice but if I can't build for Debian 6.0 > then you didn't do me a favor. :) > > holger > -- best regards, Max, http://fairwaves.co From laforge at gnumonks.org Wed Aug 20 18:21:13 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:21:13 +0200 Subject: Request for the Network Measurement Report info In-Reply-To: References: Message-ID: <20140820182113.GJ16966@nataraja> Hi Ravi, On Mon, Jul 28, 2014 at 12:09:09PM +0530, Ravi Shankar wrote: > Is it possible to get the Network Measurement Reports (NMRs) (This report > comprises of Serving and neighboring cell-id , received signal strengths, > timing advance, time of arrival values etc) of a particular Number/IMSI > using OpenBSC. In which format would you need the data? This data is needed by the BSC only for reasons of hand-over, and as OpenBSC/OsmoNITB implements the BSC, there is normally no reason for exposing them. > I am aware that we get these fields from the normal BSC. What is the 'normal BSC'? Which interface is that data made available? Are you aware of any standard interface to do so? Also: Have you seen the 'logging level meas debug' output of OpenBSC? -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From laforge at gnumonks.org Mon Aug 11 07:59:47 2014 From: laforge at gnumonks.org (Harald Welte) Date: Mon, 11 Aug 2014 09:59:47 +0200 Subject: [PATCH] sysmobts: Deal with ciphering when we have a transport clash In-Reply-To: <1407539453-19468-1-git-send-email-holger@moiji-mobile.com> References: <1407539453-19468-1-git-send-email-holger@moiji-mobile.com> Message-ID: <20140811075947.GL13764@nataraja> Hi Holger, the patches look fine to me, although it hurts that such a hack and layering violations is actually needed. I'm wondering if the spec designers didn't come up with a more elegant method. In OpenBSC we could of course disable early classmark sending, but we cannot exclude osmo-bts / sysmobts from being used with other implementations either. What about OpenBSC waiting for the classmark change to arrive _if_ early classmark sending is enabled? At least, if A5/4 is ever used, this is the only way to support it anyway, as A5/4 is indicated only in CM3, and CM3 is only part of CLASSMARK CHANGE, but not part of the CM SERVICE REQUEST or PAGING RESPONSE. However, as we are probably all quite sure that the GSM industry is not capable of rolling out a 'new' cipher in less than 10 years, I'm not sure if we should worry about this here. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From jerlbeck at sysmocom.de Thu Aug 14 07:11:04 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 14 Aug 2014 09:11:04 +0200 Subject: [PATCH] gbproxy: Add gbprox_clear_patch_filter() (Coverity) Message-ID: <1408000264-9733-1-git-send-email-jerlbeck@sysmocom.de> Add a separate function to clear the IMSI filter to be used instead of gbprox_set_patch_filter(cfg, NULL, ...). Albeit it fixes a Coverity issue (Unchecked return value), it is a false positive, since the return value is always 0 in these cases. Nevertheless it is more obvious what happens when an explicit clear function is called. Using NULL as filter argument of gbprox_set_patch_filter still clears the filter. Fixes: Coverity CID 1231255 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gb_proxy.h | 1 + openbsc/src/gprs/gb_proxy.c | 13 +++++++++---- openbsc/src/gprs/gb_proxy_vty.c | 4 ++-- openbsc/tests/gbproxy/gbproxy_test.c | 6 ++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h index 039a9a1..d6dde10 100644 --- a/openbsc/include/openbsc/gb_proxy.h +++ b/openbsc/include/openbsc/gb_proxy.h @@ -115,6 +115,7 @@ void gbprox_reset(struct gbproxy_config *cfg); int gbprox_set_patch_filter(struct gbproxy_config *cfg, const char *filter, const char **err_msg); +void gbprox_clear_patch_filter(struct gbproxy_config *cfg); void gbprox_delete_tlli(struct gbproxy_peer *peer, struct gbproxy_tlli_info *tlli_info); diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index a8ce3cc..64fb55b 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -481,16 +481,21 @@ static void gbprox_delete_tllis(struct gbproxy_peer *peer) OSMO_ASSERT(llist_empty(&state->enabled_tllis)); } +void gbprox_clear_patch_filter(struct gbproxy_config *cfg) +{ + if (cfg->check_imsi) { + regfree(&cfg->imsi_re_comp); + cfg->check_imsi = 0; + } +} + int gbprox_set_patch_filter(struct gbproxy_config *cfg, const char *filter, const char **err_msg) { static char err_buf[300]; int rc; - if (cfg->check_imsi) { - regfree(&cfg->imsi_re_comp); - cfg->check_imsi = 0; - } + gbprox_clear_patch_filter(cfg); if (!filter) return 0; diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c index ec73ae6..9574a45 100644 --- a/openbsc/src/gprs/gb_proxy_vty.c +++ b/openbsc/src/gprs/gb_proxy_vty.c @@ -193,7 +193,7 @@ static int set_core_apn(struct vty *vty, const char *apn, const char *filter) talloc_free(g_cfg->core_apn); g_cfg->core_apn = NULL; g_cfg->core_apn_size = 0; - gbprox_set_patch_filter(g_cfg, NULL, NULL); + gbprox_clear_patch_filter(g_cfg); return CMD_SUCCESS; } @@ -206,7 +206,7 @@ static int set_core_apn(struct vty *vty, const char *apn, const char *filter) } if (!filter) { - gbprox_set_patch_filter(g_cfg, NULL, NULL); + gbprox_clear_patch_filter(g_cfg); } else if (gbprox_set_patch_filter(g_cfg, filter, &err_msg) != 0) { vty_out(vty, "Match expression invalid: %s%s", err_msg, VTY_NEWLINE); diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index 964c6da..5363749 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -1571,6 +1571,12 @@ static void test_gbproxy_imsi_matching(void) OSMO_ASSERT(gbprox_set_patch_filter(&cfg, NULL, &err_msg) == 0); OSMO_ASSERT(cfg.check_imsi == 0); + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + gbprox_clear_patch_filter(&cfg); + OSMO_ASSERT(cfg.check_imsi == 0); + peer = gbproxy_peer_alloc(&cfg, 20); OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0); -- 1.9.1 From laforge at gnumonks.org Wed Aug 20 18:12:40 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:12:40 +0200 Subject: Moving libctrl to libosmocore Message-ID: <20140820181240.GI16966@nataraja> Hi Daniel, I am currently working on moving the control interface to libosmocore, you can find the status in the 'laforge/libctrl' branch. The reason behind this is that I will be adding a control interface to osmo-bts soon. The first dozens of commits is basically a filtered list of commits from the openbsc repository. The last few commits are towards making it build outside libosmocore. Most of the commits are pretty simple and uninteresting. However, there is one change that I would like to ask you to review: adf2530fc3c9d45dd1d528cd6d92d462702e3f19 where I'm trying to avoid using the openbsc-global 'tall_bsc_ctx' and introduce a more hierarchical inheritance of allocations. As this is the first time I've looked at the control interface, I might have made some wrong decisions there. The remaining steps are: * remove 'struct gsm_network' as reference and replace with a 'void * data' or 'void *priv' field * possibly rename/prefix the function names, so we end up with osmoctrl_* for the symbol names. 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 laforge at gnumonks.org Wed Aug 20 18:15:06 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:06 +0200 Subject: [PATCH 1/5] libctrl: Remove reference to 'DNAT' in favor of 'DCTRL' Message-ID: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> --- src/ctrl/control_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index ca59d8c..156a24f 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -248,7 +248,7 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) on = 1; ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); if (ret != 0) { - LOGP(DNAT, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); + LOGP(DCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); close(fd); return ret; } -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:06 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:06 +0200 Subject: [PATCH 1/5] libctrl: Remove reference to 'DNAT' in favor of 'DCTRL' Message-ID: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> --- src/ctrl/control_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index ca59d8c..156a24f 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -248,7 +248,7 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) on = 1; ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); if (ret != 0) { - LOGP(DNAT, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); + LOGP(DCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); close(fd); return ret; } -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:07 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:07 +0200 Subject: [PATCH 2/5] libctrl: remove openbsc headers, convert from make_sock to libosmocore In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-2-git-send-email-laforge@gnumonks.org> --- include/osmocom/ctrl/control_cmd.h | 3 +-- include/osmocom/ctrl/control_if.h | 6 ++++-- src/ctrl/control_cmd.c | 4 +--- src/ctrl/control_if.c | 24 ++++++++---------------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index 2e6863a..10717ac 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -4,11 +4,10 @@ #include #include #include +#include #include -#include - #define CTRL_CMD_ERROR -1 #define CTRL_CMD_HANDLED 0 #define CTRL_CMD_REPLY 1 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index d103332..9ab3b2a 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -2,8 +2,10 @@ #define _CONTROL_IF_H #include -#include -#include +#include + +/* FIXME: this must go */ +struct gsm_network; typedef int (*ctrl_cmd_handler)(struct ctrl_cmd *, void *); diff --git a/src/ctrl/control_cmd.c b/src/ctrl/control_cmd.c index 44cfa48..45e517d 100644 --- a/src/ctrl/control_cmd.c +++ b/src/ctrl/control_cmd.c @@ -29,9 +29,7 @@ #include #include -#include -#include -#include +#include #include #include diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 156a24f..7ce8bf6 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -38,31 +38,21 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include +#include #include #include #include #include #include +#include -#include +#include #include #include -#include -#include - vector ctrl_node_vec; /* Send command to all */ @@ -551,8 +541,10 @@ struct ctrl_handle *controlif_setup(struct gsm_network *gsmnet, uint16_t port, goto err; /* Listen for control connections */ - ret = make_sock(&ctrl->listen_fd, IPPROTO_TCP, INADDR_LOOPBACK, port, - 0, listen_fd_cb, ctrl); + ctrl->listen_fd.cb = listen_fd_cb; + ctrl->listen_fd.data = ctrl; + ret = osmo_sock_init_ofd(&ctrl->listen_fd, AF_INET, SOCK_STREAM, IPPROTO_TCP, + "127.0.0.1", port, OSMO_SOCK_F_BIND); if (ret < 0) goto err_vec; -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:07 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:07 +0200 Subject: [PATCH 2/5] libctrl: remove openbsc headers, convert from make_sock to libosmocore In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-2-git-send-email-laforge@gnumonks.org> --- include/osmocom/ctrl/control_cmd.h | 3 +-- include/osmocom/ctrl/control_if.h | 6 ++++-- src/ctrl/control_cmd.c | 4 +--- src/ctrl/control_if.c | 24 ++++++++---------------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index 2e6863a..10717ac 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -4,11 +4,10 @@ #include #include #include +#include #include -#include - #define CTRL_CMD_ERROR -1 #define CTRL_CMD_HANDLED 0 #define CTRL_CMD_REPLY 1 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index d103332..9ab3b2a 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -2,8 +2,10 @@ #define _CONTROL_IF_H #include -#include -#include +#include + +/* FIXME: this must go */ +struct gsm_network; typedef int (*ctrl_cmd_handler)(struct ctrl_cmd *, void *); diff --git a/src/ctrl/control_cmd.c b/src/ctrl/control_cmd.c index 44cfa48..45e517d 100644 --- a/src/ctrl/control_cmd.c +++ b/src/ctrl/control_cmd.c @@ -29,9 +29,7 @@ #include #include -#include -#include -#include +#include #include #include diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 156a24f..7ce8bf6 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -38,31 +38,21 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include +#include #include #include #include #include #include +#include -#include +#include #include #include -#include -#include - vector ctrl_node_vec; /* Send command to all */ @@ -551,8 +541,10 @@ struct ctrl_handle *controlif_setup(struct gsm_network *gsmnet, uint16_t port, goto err; /* Listen for control connections */ - ret = make_sock(&ctrl->listen_fd, IPPROTO_TCP, INADDR_LOOPBACK, port, - 0, listen_fd_cb, ctrl); + ctrl->listen_fd.cb = listen_fd_cb; + ctrl->listen_fd.data = ctrl; + ret = osmo_sock_init_ofd(&ctrl->listen_fd, AF_INET, SOCK_STREAM, IPPROTO_TCP, + "127.0.0.1", port, OSMO_SOCK_F_BIND); if (ret < 0) goto err_vec; -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:08 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:08 +0200 Subject: [PATCH 3/5] libctrl: Avoid using external tall_bsc_ctx In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-3-git-send-email-laforge@gnumonks.org> Instead of using one flat talloc context (and one that is specific to openbsc), we should attach the objects to whatever parent context they are being used in. --- src/ctrl/control_if.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 7ce8bf6..a208071 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -96,7 +96,7 @@ struct ctrl_cmd *ctrl_cmd_trap(struct ctrl_cmd *cmd) { struct ctrl_cmd *trap; - trap = ctrl_cmd_cpy(tall_bsc_ctx, cmd); + trap = ctrl_cmd_cpy(cmd, cmd); if (!trap) return NULL; @@ -281,10 +281,10 @@ static uint64_t get_rate_ctr_value(const struct rate_ctr *ctr, int intv) } } -static char *get_all_rate_ctr_in_group(const struct rate_ctr_group *ctrg, int intv) +static char *get_all_rate_ctr_in_group(void *ctx, const struct rate_ctr_group *ctrg, int intv) { int i; - char *counters = talloc_strdup(tall_bsc_ctx, ""); + char *counters = talloc_strdup(ctx, ""); if (!counters) return NULL; @@ -314,7 +314,7 @@ static int get_rate_ctr_group(const char *ctr_group, int intv, struct ctrl_cmd * if (!ctrg) break; - counters = get_all_rate_ctr_in_group(ctrg, intv); + counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); if (!counters) goto oom; @@ -340,7 +340,7 @@ static int get_rate_ctr_group_idx(const struct rate_ctr_group *ctrg, int intv, s { char *counters; - counters = get_all_rate_ctr_in_group(ctrg, intv); + counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); if (!counters) goto oom; @@ -527,7 +527,7 @@ struct ctrl_handle *controlif_setup(struct gsm_network *gsmnet, uint16_t port, int ret; struct ctrl_handle *ctrl; - ctrl = talloc_zero(tall_bsc_ctx, struct ctrl_handle); + ctrl = talloc_zero(gsmnet, struct ctrl_handle); if (!ctrl) return NULL; -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:08 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:08 +0200 Subject: [PATCH 3/5] libctrl: Avoid using external tall_bsc_ctx In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-3-git-send-email-laforge@gnumonks.org> Instead of using one flat talloc context (and one that is specific to openbsc), we should attach the objects to whatever parent context they are being used in. --- src/ctrl/control_if.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 7ce8bf6..a208071 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -96,7 +96,7 @@ struct ctrl_cmd *ctrl_cmd_trap(struct ctrl_cmd *cmd) { struct ctrl_cmd *trap; - trap = ctrl_cmd_cpy(tall_bsc_ctx, cmd); + trap = ctrl_cmd_cpy(cmd, cmd); if (!trap) return NULL; @@ -281,10 +281,10 @@ static uint64_t get_rate_ctr_value(const struct rate_ctr *ctr, int intv) } } -static char *get_all_rate_ctr_in_group(const struct rate_ctr_group *ctrg, int intv) +static char *get_all_rate_ctr_in_group(void *ctx, const struct rate_ctr_group *ctrg, int intv) { int i; - char *counters = talloc_strdup(tall_bsc_ctx, ""); + char *counters = talloc_strdup(ctx, ""); if (!counters) return NULL; @@ -314,7 +314,7 @@ static int get_rate_ctr_group(const char *ctr_group, int intv, struct ctrl_cmd * if (!ctrg) break; - counters = get_all_rate_ctr_in_group(ctrg, intv); + counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); if (!counters) goto oom; @@ -340,7 +340,7 @@ static int get_rate_ctr_group_idx(const struct rate_ctr_group *ctrg, int intv, s { char *counters; - counters = get_all_rate_ctr_in_group(ctrg, intv); + counters = get_all_rate_ctr_in_group(cmd, ctrg, intv); if (!counters) goto oom; @@ -527,7 +527,7 @@ struct ctrl_handle *controlif_setup(struct gsm_network *gsmnet, uint16_t port, int ret; struct ctrl_handle *ctrl; - ctrl = talloc_zero(tall_bsc_ctx, struct ctrl_handle); + ctrl = talloc_zero(gsmnet, struct ctrl_handle); if (!ctrl) return NULL; -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:09 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:09 +0200 Subject: [PATCH 4/5] libctrl: Add DLCTRL as logging context for the control interface In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-4-git-send-email-laforge@gnumonks.org> ... and make libctrl code use it --- include/osmocom/core/logging.h | 3 ++- src/ctrl/control_cmd.c | 30 +++++++++++++++--------------- src/ctrl/control_if.c | 26 +++++++++++++------------- src/logging.c | 5 +++++ 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index caeea06..3c5e7b1 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -67,7 +67,8 @@ void logp(int subsys, const char *file, int line, int cont, const char *format, #define DLMI -5 #define DLMIB -6 #define DLSMS -7 -#define OSMO_NUM_DLIB 7 +#define DLCTRL -8 +#define OSMO_NUM_DLIB 8 struct log_category { uint8_t loglevel; diff --git a/src/ctrl/control_cmd.c b/src/ctrl/control_cmd.c index 45e517d..8c92033 100644 --- a/src/ctrl/control_cmd.c +++ b/src/ctrl/control_cmd.c @@ -188,7 +188,7 @@ static void create_cmd_struct(struct ctrl_cmd_struct *cmd, const char *name) for (cur = name, word = NULL; cur[0] != '\0'; ++cur) { /* warn about optionals */ if (cur[0] == '(' || cur[0] == ')' || cur[0] == '|') { - LOGP(DCTRL, LOGL_ERROR, + LOGP(DLCTRL, LOGL_ERROR, "Optionals are not supported in '%s'\n", name); goto failure; } @@ -223,7 +223,7 @@ int ctrl_cmd_install(enum ctrl_node_type node, struct ctrl_cmd_element *cmd) if (!cmds_vec) { cmds_vec = vector_init(5); if (!cmds_vec) { - LOGP(DCTRL, LOGL_ERROR, "vector_init failed.\n"); + LOGP(DLCTRL, LOGL_ERROR, "vector_init failed.\n"); return -ENOMEM; } vector_set_index(ctrl_node_vec, node, cmds_vec); @@ -291,7 +291,7 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) cmd = talloc_zero(ctx, struct ctrl_cmd); if (!cmd) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate.\n"); return NULL; } @@ -333,11 +333,11 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "GET incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "GET Command incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "GET Command incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); - LOGP(DCTRL, LOGL_DEBUG, "Command: GET %s\n", cmd->variable); + LOGP(DLCTRL, LOGL_DEBUG, "Command: GET %s\n", cmd->variable); break; case CTRL_TYPE_SET: var = strtok_r(NULL, " ", &saveptr); @@ -345,14 +345,14 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var || !val) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "SET incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "SET Command incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "SET Command incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); cmd->value = talloc_strdup(cmd, val); if (!cmd->variable || !cmd->value) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: SET %s = %s\n", cmd->variable, cmd->value); + LOGP(DLCTRL, LOGL_DEBUG, "Command: SET %s = %s\n", cmd->variable, cmd->value); break; case CTRL_TYPE_GET_REPLY: case CTRL_TYPE_SET_REPLY: @@ -362,14 +362,14 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var || !val) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "Trap/Reply incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "Trap/Reply incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "Trap/Reply incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); cmd->reply = talloc_strdup(cmd, val); if (!cmd->variable || !cmd->reply) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: TRAP/REPLY %s: %s\n", cmd->variable, cmd->reply); + LOGP(DLCTRL, LOGL_DEBUG, "Command: TRAP/REPLY %s: %s\n", cmd->variable, cmd->reply); break; case CTRL_TYPE_ERROR: var = strtok_r(NULL, "\0", &saveptr); @@ -380,7 +380,7 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) cmd->reply = talloc_strdup(cmd, var); if (!cmd->reply) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: ERROR %s\n", cmd->reply); + LOGP(DLCTRL, LOGL_DEBUG, "Command: ERROR %s\n", cmd->reply); break; case CTRL_TYPE_UNKNOWN: default: @@ -420,7 +420,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s", type, cmd->id, cmd->variable); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -435,7 +435,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s %s", type, cmd->id, cmd->variable, cmd->value); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -452,7 +452,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s %s", type, cmd->id, cmd->variable, cmd->reply); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -467,7 +467,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s", type, cmd->id, cmd->reply); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -476,7 +476,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) talloc_free(tmp); break; default: - LOGP(DCTRL, LOGL_NOTICE, "Unknown command type %i\n", cmd->type); + LOGP(DLCTRL, LOGL_NOTICE, "Unknown command type %i\n", cmd->type); goto err; break; } diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index a208071..007e0fe 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -77,7 +77,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd) msg = ctrl_cmd_make(cmd); if (!msg) { - LOGP(DCTRL, LOGL_ERROR, "Could not generate msg\n"); + LOGP(DLCTRL, LOGL_ERROR, "Could not generate msg\n"); return -1; } @@ -86,7 +86,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd) ret = osmo_wqueue_enqueue(queue, msg); if (ret != 0) { - LOGP(DCTRL, LOGL_ERROR, "Failed to enqueue the command.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to enqueue the command.\n"); msgb_free(msg); } return ret; @@ -136,27 +136,27 @@ static int handle_control_read(struct osmo_fd * bfd) if (ret == -EAGAIN) return 0; if (ret == 0) - LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n"); + LOGP(DLCTRL, LOGL_INFO, "The control connection was closed\n"); else - LOGP(DCTRL, LOGL_ERROR, "Failed to parse ip access message: %d\n", ret); + LOGP(DLCTRL, LOGL_ERROR, "Failed to parse ip access message: %d\n", ret); goto err; } if (msg->len < sizeof(*iph) + sizeof(*iph_ext)) { - LOGP(DCTRL, LOGL_ERROR, "The message is too short.\n"); + LOGP(DLCTRL, LOGL_ERROR, "The message is too short.\n"); goto err; } iph = (struct ipaccess_head *) msg->data; if (iph->proto != IPAC_PROTO_OSMO) { - LOGP(DCTRL, LOGL_ERROR, "Protocol mismatch. We got 0x%x\n", iph->proto); + LOGP(DLCTRL, LOGL_ERROR, "Protocol mismatch. We got 0x%x\n", iph->proto); goto err; } iph_ext = (struct ipaccess_head_ext *) iph->data; if (iph_ext->proto != IPAC_PROTO_EXT_CTRL) { - LOGP(DCTRL, LOGL_ERROR, "Extended protocol mismatch. We got 0x%x\n", iph_ext->proto); + LOGP(DLCTRL, LOGL_ERROR, "Extended protocol mismatch. We got 0x%x\n", iph_ext->proto); goto err; } @@ -174,7 +174,7 @@ static int handle_control_read(struct osmo_fd * bfd) cmd = talloc_zero(ccon, struct ctrl_cmd); if (!cmd) goto err; - LOGP(DCTRL, LOGL_ERROR, "Command parser error.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Command parser error.\n"); cmd->type = CTRL_TYPE_ERROR; cmd->id = "err"; cmd->reply = "Command parser error."; @@ -197,7 +197,7 @@ static int control_write_cb(struct osmo_fd *bfd, struct msgb *msg) rc = write(bfd->fd, msg->data, msg->len); if (rc != msg->len) - LOGP(DCTRL, LOGL_ERROR, "Failed to write message to the control connection.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to write message to the control connection.\n"); return rc; } @@ -232,19 +232,19 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) perror("accept"); return fd; } - LOGP(DCTRL, LOGL_INFO, "accept()ed new control connection from %s\n", + LOGP(DLCTRL, LOGL_INFO, "accept()ed new control connection from %s\n", inet_ntoa(sa.sin_addr)); on = 1; ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); if (ret != 0) { - LOGP(DCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); + LOGP(DLCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); close(fd); return ret; } ccon = ctrl_connection_alloc(listen_bfd->data); if (!ccon) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate.\n"); close(fd); return -1; } @@ -258,7 +258,7 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) ret = osmo_fd_register(&ccon->write_queue.bfd); if (ret < 0) { - LOGP(DCTRL, LOGL_ERROR, "Could not register FD.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Could not register FD.\n"); close(ccon->write_queue.bfd.fd); talloc_free(ccon); } diff --git a/src/logging.c b/src/logging.c index 2e3a80a..f9d789d 100644 --- a/src/logging.c +++ b/src/logging.c @@ -106,6 +106,11 @@ static const struct log_info_cat internal_cat[OSMO_NUM_DLIB] = { .enabled = 1, .loglevel = LOGL_NOTICE, .color = "\033[1;38m", }, + [INT2IDX(DLCTRL)] = { + .name = "DLCTRL", + .description = "Control Interface", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; /*! \brief descriptive string for each log level */ -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:09 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:09 +0200 Subject: [PATCH 4/5] libctrl: Add DLCTRL as logging context for the control interface In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-4-git-send-email-laforge@gnumonks.org> ... and make libctrl code use it --- include/osmocom/core/logging.h | 3 ++- src/ctrl/control_cmd.c | 30 +++++++++++++++--------------- src/ctrl/control_if.c | 26 +++++++++++++------------- src/logging.c | 5 +++++ 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index caeea06..3c5e7b1 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -67,7 +67,8 @@ void logp(int subsys, const char *file, int line, int cont, const char *format, #define DLMI -5 #define DLMIB -6 #define DLSMS -7 -#define OSMO_NUM_DLIB 7 +#define DLCTRL -8 +#define OSMO_NUM_DLIB 8 struct log_category { uint8_t loglevel; diff --git a/src/ctrl/control_cmd.c b/src/ctrl/control_cmd.c index 45e517d..8c92033 100644 --- a/src/ctrl/control_cmd.c +++ b/src/ctrl/control_cmd.c @@ -188,7 +188,7 @@ static void create_cmd_struct(struct ctrl_cmd_struct *cmd, const char *name) for (cur = name, word = NULL; cur[0] != '\0'; ++cur) { /* warn about optionals */ if (cur[0] == '(' || cur[0] == ')' || cur[0] == '|') { - LOGP(DCTRL, LOGL_ERROR, + LOGP(DLCTRL, LOGL_ERROR, "Optionals are not supported in '%s'\n", name); goto failure; } @@ -223,7 +223,7 @@ int ctrl_cmd_install(enum ctrl_node_type node, struct ctrl_cmd_element *cmd) if (!cmds_vec) { cmds_vec = vector_init(5); if (!cmds_vec) { - LOGP(DCTRL, LOGL_ERROR, "vector_init failed.\n"); + LOGP(DLCTRL, LOGL_ERROR, "vector_init failed.\n"); return -ENOMEM; } vector_set_index(ctrl_node_vec, node, cmds_vec); @@ -291,7 +291,7 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) cmd = talloc_zero(ctx, struct ctrl_cmd); if (!cmd) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate.\n"); return NULL; } @@ -333,11 +333,11 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "GET incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "GET Command incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "GET Command incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); - LOGP(DCTRL, LOGL_DEBUG, "Command: GET %s\n", cmd->variable); + LOGP(DLCTRL, LOGL_DEBUG, "Command: GET %s\n", cmd->variable); break; case CTRL_TYPE_SET: var = strtok_r(NULL, " ", &saveptr); @@ -345,14 +345,14 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var || !val) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "SET incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "SET Command incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "SET Command incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); cmd->value = talloc_strdup(cmd, val); if (!cmd->variable || !cmd->value) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: SET %s = %s\n", cmd->variable, cmd->value); + LOGP(DLCTRL, LOGL_DEBUG, "Command: SET %s = %s\n", cmd->variable, cmd->value); break; case CTRL_TYPE_GET_REPLY: case CTRL_TYPE_SET_REPLY: @@ -362,14 +362,14 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) if (!var || !val) { cmd->type = CTRL_TYPE_ERROR; cmd->reply = "Trap/Reply incomplete"; - LOGP(DCTRL, LOGL_NOTICE, "Trap/Reply incomplete\n"); + LOGP(DLCTRL, LOGL_NOTICE, "Trap/Reply incomplete\n"); goto err; } cmd->variable = talloc_strdup(cmd, var); cmd->reply = talloc_strdup(cmd, val); if (!cmd->variable || !cmd->reply) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: TRAP/REPLY %s: %s\n", cmd->variable, cmd->reply); + LOGP(DLCTRL, LOGL_DEBUG, "Command: TRAP/REPLY %s: %s\n", cmd->variable, cmd->reply); break; case CTRL_TYPE_ERROR: var = strtok_r(NULL, "\0", &saveptr); @@ -380,7 +380,7 @@ struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg) cmd->reply = talloc_strdup(cmd, var); if (!cmd->reply) goto oom; - LOGP(DCTRL, LOGL_DEBUG, "Command: ERROR %s\n", cmd->reply); + LOGP(DLCTRL, LOGL_DEBUG, "Command: ERROR %s\n", cmd->reply); break; case CTRL_TYPE_UNKNOWN: default: @@ -420,7 +420,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s", type, cmd->id, cmd->variable); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -435,7 +435,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s %s", type, cmd->id, cmd->variable, cmd->value); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -452,7 +452,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s %s", type, cmd->id, cmd->variable, cmd->reply); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -467,7 +467,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) tmp = talloc_asprintf(cmd, "%s %s %s", type, cmd->id, cmd->reply); if (!tmp) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate cmd.\n"); goto err; } @@ -476,7 +476,7 @@ struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd) talloc_free(tmp); break; default: - LOGP(DCTRL, LOGL_NOTICE, "Unknown command type %i\n", cmd->type); + LOGP(DLCTRL, LOGL_NOTICE, "Unknown command type %i\n", cmd->type); goto err; break; } diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index a208071..007e0fe 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -77,7 +77,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd) msg = ctrl_cmd_make(cmd); if (!msg) { - LOGP(DCTRL, LOGL_ERROR, "Could not generate msg\n"); + LOGP(DLCTRL, LOGL_ERROR, "Could not generate msg\n"); return -1; } @@ -86,7 +86,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd) ret = osmo_wqueue_enqueue(queue, msg); if (ret != 0) { - LOGP(DCTRL, LOGL_ERROR, "Failed to enqueue the command.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to enqueue the command.\n"); msgb_free(msg); } return ret; @@ -136,27 +136,27 @@ static int handle_control_read(struct osmo_fd * bfd) if (ret == -EAGAIN) return 0; if (ret == 0) - LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n"); + LOGP(DLCTRL, LOGL_INFO, "The control connection was closed\n"); else - LOGP(DCTRL, LOGL_ERROR, "Failed to parse ip access message: %d\n", ret); + LOGP(DLCTRL, LOGL_ERROR, "Failed to parse ip access message: %d\n", ret); goto err; } if (msg->len < sizeof(*iph) + sizeof(*iph_ext)) { - LOGP(DCTRL, LOGL_ERROR, "The message is too short.\n"); + LOGP(DLCTRL, LOGL_ERROR, "The message is too short.\n"); goto err; } iph = (struct ipaccess_head *) msg->data; if (iph->proto != IPAC_PROTO_OSMO) { - LOGP(DCTRL, LOGL_ERROR, "Protocol mismatch. We got 0x%x\n", iph->proto); + LOGP(DLCTRL, LOGL_ERROR, "Protocol mismatch. We got 0x%x\n", iph->proto); goto err; } iph_ext = (struct ipaccess_head_ext *) iph->data; if (iph_ext->proto != IPAC_PROTO_EXT_CTRL) { - LOGP(DCTRL, LOGL_ERROR, "Extended protocol mismatch. We got 0x%x\n", iph_ext->proto); + LOGP(DLCTRL, LOGL_ERROR, "Extended protocol mismatch. We got 0x%x\n", iph_ext->proto); goto err; } @@ -174,7 +174,7 @@ static int handle_control_read(struct osmo_fd * bfd) cmd = talloc_zero(ccon, struct ctrl_cmd); if (!cmd) goto err; - LOGP(DCTRL, LOGL_ERROR, "Command parser error.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Command parser error.\n"); cmd->type = CTRL_TYPE_ERROR; cmd->id = "err"; cmd->reply = "Command parser error."; @@ -197,7 +197,7 @@ static int control_write_cb(struct osmo_fd *bfd, struct msgb *msg) rc = write(bfd->fd, msg->data, msg->len); if (rc != msg->len) - LOGP(DCTRL, LOGL_ERROR, "Failed to write message to the control connection.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to write message to the control connection.\n"); return rc; } @@ -232,19 +232,19 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) perror("accept"); return fd; } - LOGP(DCTRL, LOGL_INFO, "accept()ed new control connection from %s\n", + LOGP(DLCTRL, LOGL_INFO, "accept()ed new control connection from %s\n", inet_ntoa(sa.sin_addr)); on = 1; ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); if (ret != 0) { - LOGP(DCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); + LOGP(DLCTRL, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno)); close(fd); return ret; } ccon = ctrl_connection_alloc(listen_bfd->data); if (!ccon) { - LOGP(DCTRL, LOGL_ERROR, "Failed to allocate.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Failed to allocate.\n"); close(fd); return -1; } @@ -258,7 +258,7 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what) ret = osmo_fd_register(&ccon->write_queue.bfd); if (ret < 0) { - LOGP(DCTRL, LOGL_ERROR, "Could not register FD.\n"); + LOGP(DLCTRL, LOGL_ERROR, "Could not register FD.\n"); close(ccon->write_queue.bfd.fd); talloc_free(ccon); } diff --git a/src/logging.c b/src/logging.c index 2e3a80a..f9d789d 100644 --- a/src/logging.c +++ b/src/logging.c @@ -106,6 +106,11 @@ static const struct log_info_cat internal_cat[OSMO_NUM_DLIB] = { .enabled = 1, .loglevel = LOGL_NOTICE, .color = "\033[1;38m", }, + [INT2IDX(DLCTRL)] = { + .name = "DLCTRL", + .description = "Control Interface", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; /*! \brief descriptive string for each log level */ -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:10 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:10 +0200 Subject: [PATCH 5/5] libctrl: autotools build system integration In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-5-git-send-email-laforge@gnumonks.org> Now we actually build the recently-imported libctrl --- Makefile.am | 2 +- configure.ac | 1 + src/ctrl/Makefile.am | 15 ++++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 717d3db..b7bad41 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src src/vty src/codec src/gsm src/gb tests utils +SUBDIRS = include src src/vty src/codec src/gsm src/gb src/ctrl tests utils pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmocore.pc libosmocodec.pc libosmovty.pc libosmogsm.pc \ diff --git a/configure.ac b/configure.ac index eaaab50..a902eb5 100644 --- a/configure.ac +++ b/configure.ac @@ -192,6 +192,7 @@ AC_OUTPUT( src/codec/Makefile src/gsm/Makefile src/gb/Makefile + src/ctrl/Makefile tests/Makefile utils/Makefile Doxyfile.core diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 4f039c8..29a8ee2 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -1,7 +1,12 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +# This is _NOT_ the library release version, it's an API version. +# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification +LIBVERSION=0:0:0 -noinst_LIBRARIES = libctrl.a +AM_CFLAGS = -Wall $(all_includes) -I$(top_srcdir)/include -libctrl_a_SOURCES = control_if.c control_cmd.c +lib_LTLIBRARIES = libosmoctrl.la + +libosmoctrl_la_SOURCES = control_cmd.c control_if.c + +libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) -version-info $(LIBVERSION) -no-undefined +libosmoctrl_la_LIBADD = $(top_builddir)/src/libosmocore.la -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 18:15:10 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 20:15:10 +0200 Subject: [PATCH 5/5] libctrl: autotools build system integration In-Reply-To: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> References: <1408558510-10364-1-git-send-email-laforge@gnumonks.org> Message-ID: <1408558510-10364-5-git-send-email-laforge@gnumonks.org> Now we actually build the recently-imported libctrl --- Makefile.am | 2 +- configure.ac | 1 + src/ctrl/Makefile.am | 15 ++++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 717d3db..b7bad41 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src src/vty src/codec src/gsm src/gb tests utils +SUBDIRS = include src src/vty src/codec src/gsm src/gb src/ctrl tests utils pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmocore.pc libosmocodec.pc libosmovty.pc libosmogsm.pc \ diff --git a/configure.ac b/configure.ac index eaaab50..a902eb5 100644 --- a/configure.ac +++ b/configure.ac @@ -192,6 +192,7 @@ AC_OUTPUT( src/codec/Makefile src/gsm/Makefile src/gb/Makefile + src/ctrl/Makefile tests/Makefile utils/Makefile Doxyfile.core diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 4f039c8..29a8ee2 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -1,7 +1,12 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) -AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS) +# This is _NOT_ the library release version, it's an API version. +# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification +LIBVERSION=0:0:0 -noinst_LIBRARIES = libctrl.a +AM_CFLAGS = -Wall $(all_includes) -I$(top_srcdir)/include -libctrl_a_SOURCES = control_if.c control_cmd.c +lib_LTLIBRARIES = libosmoctrl.la + +libosmoctrl_la_SOURCES = control_cmd.c control_if.c + +libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) -version-info $(LIBVERSION) -no-undefined +libosmoctrl_la_LIBADD = $(top_builddir)/src/libosmocore.la -- 2.1.0.rc1 From laforge at gnumonks.org Wed Aug 20 21:58:50 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 20 Aug 2014 23:58:50 +0200 Subject: libosmocore/libosmo-abis changes + fallout Message-ID: <20140820215850.GO16966@nataraja> In preparation of the libctrl move to libosmocore[*], I had to move some IPA related functionality from libosmo-abis to libosmocore. This is required as libctrl needs IPA functions, but we cannot make a cyclic library (build) dependency between libosmocore and libosmo-abis. I took the decision to rename some of the sysmbols for consistency. This is always ugly and creates fall-out, so there never is a good time for it. I thought now it makes sense as things are undergoing modifications anyway. I was able to do 'make check / make distcheck' of libosmocore / libosmo-abis / osmo-pcu / osmo-bts and openbsc master branches with the recent commits. If I missed something, please let me know by private mail and I'm happy o clean up further. Regards, Harald [*] required to add a control interface to osmo-bts, which is required for things like managing/triggering clock recalibration on sysmobts from external programs. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From meskio at sindominio.net Sun Aug 24 18:56:27 2014 From: meskio at sindominio.net (Ruben Pollan) Date: Sun, 24 Aug 2014 13:56:27 -0500 Subject: [PATCH] Add subscriber delete command Message-ID: <1408906587-4485-1-git-send-email-meskio@sindominio.net> --- openbsc/include/openbsc/gsm_subscriber.h | 1 + openbsc/src/libbsc/gsm_subscriber_base.c | 2 +- openbsc/src/libmsc/vty_interface_layer3.c | 24 +++++++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 7aae4c3..120111b 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -101,6 +101,7 @@ int subscr_pending_kick(struct gsm_subscriber *subscr); char *subscr_name(struct gsm_subscriber *subscr); +void subscr_free(struct gsm_subscriber *subscr); int subscr_purge_inactive(struct gsm_network *net); void subscr_update_from_db(struct gsm_subscriber *subscr); void subscr_expire(struct gsm_network *net); diff --git a/openbsc/src/libbsc/gsm_subscriber_base.c b/openbsc/src/libbsc/gsm_subscriber_base.c index 5e00443..2b31e95 100644 --- a/openbsc/src/libbsc/gsm_subscriber_base.c +++ b/openbsc/src/libbsc/gsm_subscriber_base.c @@ -66,7 +66,7 @@ struct gsm_subscriber *subscr_alloc(void) return s; } -static void subscr_free(struct gsm_subscriber *subscr) +void subscr_free(struct gsm_subscriber *subscr) { llist_del(&subscr->entry); talloc_free(subscr); diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 064eca9..6b53f65 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -465,7 +465,28 @@ DEFUN(subscriber_ussd_notify, return CMD_SUCCESS; } -DEFUN(ena_subscr_authorizde, +DEFUN(ena_subscr_delete, + ena_subscr_delete_cmd, + "subscriber " SUBSCR_TYPES " ID delete", + SUBSCR_HELP "Delete subscriber in HLR\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + struct gsm_subscriber *subscr = + get_subscr_by_argv(gsmnet, argv[0], argv[1]); + + if (!subscr) { + vty_out(vty, "%% No subscriber found for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + db_subscriber_delete(subscr); + subscr_free(subscr); + + return CMD_SUCCESS; +} + +DEFUN(ena_subscr_authorized, ena_subscr_authorized_cmd, "subscriber " SUBSCR_TYPES " ID authorized (0|1)", SUBSCR_HELP "(De-)Authorize subscriber in HLR\n" @@ -982,6 +1003,7 @@ int bsc_vty_init_extra(void) install_element_ve(&show_stats_cmd); install_element_ve(&show_smsqueue_cmd); + install_element(ENABLE_NODE, &ena_subscr_delete_cmd); install_element(ENABLE_NODE, &ena_subscr_name_cmd); install_element(ENABLE_NODE, &ena_subscr_extension_cmd); install_element(ENABLE_NODE, &ena_subscr_authorized_cmd); -- 2.1.0 From meskio at sindominio.net Sun Aug 24 19:02:16 2014 From: meskio at sindominio.net (Ruben Pollan) Date: Sun, 24 Aug 2014 14:02:16 -0500 Subject: [PATCH] Add subscriber delete command In-Reply-To: <1408906587-4485-1-git-send-email-meskio@sindominio.net> References: <1408906587-4485-1-git-send-email-meskio@sindominio.net> Message-ID: <20140824190216.4234.64825@KingMob> This patch comes from some needs of rhizmoatica. It looks good in our tests, but today it's my first time looking at openbsc code and I might miss something. Cheers. -- Ruben Pollan | http://meskio.net/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- My contact info: http://meskio.net/crypto.txt -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Nos vamos a Croatan. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: signature URL: From holger at freyther.de Sun Aug 31 10:42:56 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 31 Aug 2014 12:42:56 +0200 Subject: [PATCH] Add subscriber delete command In-Reply-To: <20140824190216.4234.64825@KingMob> References: <1408906587-4485-1-git-send-email-meskio@sindominio.net> <20140824190216.4234.64825@KingMob> Message-ID: <20140831104256.GE4032@xiaoyu.lan> On Sun, Aug 24, 2014 at 02:02:16PM -0500, Ruben Pollan wrote: Hi! > This patch comes from some needs of rhizmoatica. It looks good in our tests, but > today it's my first time looking at openbsc code and I might miss something. sorry, I intendted to reply right-away and then had to rush and dropped the ball. To make sure your feature continue to work you should definately add an end-to-end test. There is one technical issue. The subscriber record is reference counted. So if you free the memory while someobody else is using it you will crash. Third, for machine to machine interaction we have the control interface which already has a command to delete the subscriber. Please have a look at src/libmsc/ctrl_commands.c:set_subscriber_delete cheers holger From meskio at sindominio.net Sun Aug 31 22:11:01 2014 From: meskio at sindominio.net (Ruben Pollan) Date: Sun, 31 Aug 2014 17:11:01 -0500 Subject: [PATCH] Add subscriber delete command In-Reply-To: <20140831104256.GE4032@xiaoyu.lan> References: <1408906587-4485-1-git-send-email-meskio@sindominio.net> <20140824190216.4234.64825@KingMob> <20140831104256.GE4032@xiaoyu.lan> Message-ID: <20140831221101.3395.74341@KingMob> Quoting Holger Hans Peter Freyther (2014-08-31 05:42:56) > On Sun, Aug 24, 2014 at 02:02:16PM -0500, Ruben Pollan wrote: > > Hi! > > > This patch comes from some needs of rhizmoatica. It looks good in our tests, but > > today it's my first time looking at openbsc code and I might miss something. > > sorry, I intendted to reply right-away and then had to rush and > dropped the ball. To make sure your feature continue to work you > should definately add an end-to-end test. > > There is one technical issue. The subscriber record is reference > counted. So if you free the memory while someobody else is using > it you will crash. > > Third, for machine to machine interaction we have the control > interface which already has a command to delete the subscriber. > Please have a look at > > src/libmsc/ctrl_commands.c:set_subscriber_delete It makes sense, I just fixed. The new patch comes in a following email. Thanks for the review. -- Ruben Pollan | http://meskio.net/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- My contact info: http://meskio.net/crypto.txt -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Nos vamos a Croatan. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: signature URL: From meskio at sindominio.net Sun Aug 31 22:13:15 2014 From: meskio at sindominio.net (Ruben Pollan) Date: Sun, 31 Aug 2014 17:13:15 -0500 Subject: [PATCH] Add subscriber delete command In-Reply-To: <20140831104256.GE4032@xiaoyu.lan> References: <20140831104256.GE4032@xiaoyu.lan> Message-ID: <1409523195-15851-1-git-send-email-meskio@sindominio.net> --- openbsc/src/libmsc/vty_interface_layer3.c | 34 ++++++++++++++++++++++++++++++- openbsc/tests/vty_test_runner.py | 10 ++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 064eca9..8890099 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -465,7 +465,38 @@ DEFUN(subscriber_ussd_notify, return CMD_SUCCESS; } -DEFUN(ena_subscr_authorizde, +DEFUN(ena_subscr_delete, + ena_subscr_delete_cmd, + "subscriber " SUBSCR_TYPES " ID delete", + SUBSCR_HELP "Delete subscriber in HLR\n") +{ + int rc; + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + struct gsm_subscriber *subscr = + get_subscr_by_argv(gsmnet, argv[0], argv[1]); + + if (!subscr) { + vty_out(vty, "%% No subscriber found for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + if (subscr->use_count != 1) { + vty_out(vty, "Removing active subscriber%s", VTY_NEWLINE); + } + + rc = db_subscriber_delete(subscr); + subscr_put(subscr); + + if (rc != 0) { + vty_out(vty, "Failed to remove subscriber%s", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(ena_subscr_authorized, ena_subscr_authorized_cmd, "subscriber " SUBSCR_TYPES " ID authorized (0|1)", SUBSCR_HELP "(De-)Authorize subscriber in HLR\n" @@ -982,6 +1013,7 @@ int bsc_vty_init_extra(void) install_element_ve(&show_stats_cmd); install_element_ve(&show_smsqueue_cmd); + install_element(ENABLE_NODE, &ena_subscr_delete_cmd); install_element(ENABLE_NODE, &ena_subscr_name_cmd); install_element(ENABLE_NODE, &ena_subscr_extension_cmd); install_element(ENABLE_NODE, &ena_subscr_authorized_cmd); diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index db8294d..c12121b 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -247,7 +247,7 @@ class TestVTYNITB(TestVTYGenericBSC): if classNum != 10: self.assertEquals(res.find("rach access-control-class " + str(classNum) + " barred"), -1) - def testSubscriberCreate(self): + def testSubscriberCreateDelete(self): self.vty.enable() imsi = "204300854013739" @@ -263,6 +263,14 @@ class TestVTYNITB(TestVTYGenericBSC): res = self.vty.command('show subscriber imsi '+imsi) self.assert_(res.find(" IMSI: "+imsi) > 0) + # Delte it + res = self.vty.command('subscriber delete imsi '+imsi) + self.assert_(res != "") + + # Now it should not be there anymore + res = self.vty.command('show subscriber imsi '+imsi) + self.assert_(res != '% No subscriber found for imsi '+imsi) + def testShowPagingGroup(self): res = self.vty.command("show paging-group 255 1234567") self.assertEqual(res, "% can't find BTS 255") -- 2.1.0 From snehasish.kar at vehere.com Tue Aug 26 13:10:37 2014 From: snehasish.kar at vehere.com (Snehasish Kar (Vehere)) Date: Tue, 26 Aug 2014 18:40:37 +0530 Subject: No subject Message-ID: Dear Groupmembers Please help me with this case. I have successfully sent rrlp request to the mobile and the mobile automatically turns its gps on as a response to it. But it doesn't provide me its location or request for any kind of assistance data. So please let me know what i am missing and what i have to do. Thanks & Regards Snehasish -------------- next part -------------- An HTML attachment was scrubbed... URL: From laforge at gnumonks.org Wed Aug 27 21:54:19 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:19 +0200 Subject: Final review of L1SAP ported to current maste Message-ID: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Dear all, the valuable L1SAP abstraction has been sitting out of master for too long time. It is a pity that this has taken so long. I've finally been able to put some time into osmo-bts again and reviewed the following patch series. It consists of mostly Andreas' work, interspersed with smaller patches/fixups that I introduced after the respective original patch from Andreas. I have started a sysmobts between all of the major steps in this patch series and did a short manual tests involving registration (LU) of two MS, mobile-to-mobile call and vty-to-mobile SMS. So far I couldn't see any problems. What has not been tested yet is the PCU interface as well as encryption support. I plan to do this later this week. I intend to merge the code after this current review cycle. Please take your time to have a look and provide feedback (if any), so we can get this over and work on new features again, rather than infrastrutural changes. I didn't yet rebase the osmo-bts-trx interface on top of the L1SAP, as I don't have a hardware setup for it, and I will leave it to the owners of such hardware to publish/push the respective code after L1SAP is merged. 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 laforge at gnumonks.org Wed Aug 27 21:54:20 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:20 +0200 Subject: [PATCH 01/33] sysmo-bts: Use correct boundaries of L1 msg when forwarding to L1 proxy In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-2-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg In case of a headroom in a message, the 'head' pointer will not point to the actual data. --- src/osmo-bts-sysmo/l1_transp_fwd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/l1_transp_fwd.c b/src/osmo-bts-sysmo/l1_transp_fwd.c index 5050705..87c230b 100644 --- a/src/osmo-bts-sysmo/l1_transp_fwd.c +++ b/src/osmo-bts-sysmo/l1_transp_fwd.c @@ -95,7 +95,7 @@ static int fwd_read_cb(struct osmo_fd *ofd) static int prim_write_cb(struct osmo_fd *ofd, struct msgb *msg) { /* write to the fd */ - return write(ofd->fd, msg->head, msg->len); + return write(ofd->fd, msg->l1h, msgb_l1len(msg)); } int l1if_transport_open(int q, struct femtol1_hdl *fl1h) -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:21 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:21 +0200 Subject: [PATCH 02/33] Add header file of PH-/MPH-/TCH-SAP interface to common part of osmo-bts In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-3-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg Instead of handling primitives directly at layer 1 specific code, osmo-bts handles primitives at common code. When all primitive are moved, the l1sap interface will: - receive PH-DATA indications and forward them to layer 2. - check for RF link loss and notify BSC. - receive TCH indications and forward them via RTP. - receive PH-RTS indications and send PH-DATA requests with content according to its logical channel. - receive TCH-RTS indications and send TCH requests with content received via RTP or loopback from TCH indications. - send MPH-INFO requests to activate, deactivate and modify logical channels and handle their confirms. - receive MPH-INFO indications with measurements from tranceiver. - forward received and transmitted PH-DATA to GSMTAP. --- include/osmo-bts/Makefile.am | 2 +- include/osmo-bts/l1sap.h | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 include/osmo-bts/l1sap.h diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am index a55e642..c18c820 100644 --- a/include/osmo-bts/Makefile.am +++ b/include/osmo-bts/Makefile.am @@ -1,3 +1,3 @@ noinst_HEADERS = abis.h bts.h bts_model.h gsm_data.h logging.h measurement.h \ oml.h paging.h rsl.h signal.h vty.h amr.h pcu_if.h pcuif_proto.h \ - handover.h msg_utils.h tx_power.h control_if.h + handover.h msg_utils.h tx_power.h control_if.h l1sap.h diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h new file mode 100644 index 0000000..a1dc303 --- /dev/null +++ b/include/osmo-bts/l1sap.h @@ -0,0 +1,71 @@ +#ifndef L1SAP_H +#define L1SAP_H + +/* timeslot and subslot from chan_nr */ +#define L1SAP_CHAN2TS(chan_nr) (chan_nr & 7) +#define L1SAP_CHAN2SS_TCHH(chan_nr) ((chan_nr >> 3) & 1) +#define L1SAP_CHAN2SS_SDCCH4(chan_nr) ((chan_nr >> 3) & 3) +#define L1SAP_CHAN2SS_SDCCH8(chan_nr) ((chan_nr >> 3) & 7) + +/* logical channel from chan_nr + link_id */ +#define L1SAP_IS_LINK_SACCH(link_id) ((link_id & 0xC0) == 0x40) +#define L1SAP_IS_CHAN_TCHF(chan_nr) ((chan_nr & 0xf8) == 0x08) +#define L1SAP_IS_CHAN_TCHH(chan_nr) ((chan_nr & 0xf0) == 0x10) +#define L1SAP_IS_CHAN_SDCCH4(chan_nr) ((chan_nr & 0xe0) == 0x20) +#define L1SAP_IS_CHAN_SDCCH8(chan_nr) ((chan_nr & 0xc0) == 0x40) +#define L1SAP_IS_CHAN_BCCH(chan_nr) ((chan_nr & 0xf8) == 0x80) +#define L1SAP_IS_CHAN_RACH(chan_nr) ((chan_nr & 0xf8) == 0x88) +#define L1SAP_IS_CHAN_AGCH_PCH(chan_nr) ((chan_nr & 0xf8) == 0x90) + +/* rach type from ra */ +#define L1SAP_IS_PACKET_RACH(ra) ((ra & 0xf0) == 0x70) + +/* CCCH block from frame number */ +#define L1SAP_FN2CCCHBLOCK(fn) ((fn % 51) / 5 - 1) + +/* PTCH layout from frame number */ +#define L1SAP_FN2MACBLOCK(fn) ((fn % 52) / 4) +#define L1SAP_FN2PTCCHBLOCK(fn) ((fn / 52) & 7) +#define L1SAP_IS_PTCCH(fn) ((fn % 52) == 12) + +/* subslot from any chan_nr */ +static inline uint8_t l1sap_chan2ss(uint8_t chan_nr) +{ + if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) + return L1SAP_CHAN2SS_SDCCH8(chan_nr); + if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) + return L1SAP_CHAN2SS_SDCCH4(chan_nr); + if (L1SAP_IS_CHAN_TCHH(chan_nr)) + return L1SAP_CHAN2SS_TCHH(chan_nr); + return 0; +} + + +/* allocate a msgb containing a osmo_phsap_prim + optional l2 data */ +struct msgb *l1sap_msgb_alloc(unsigned int l2_len); + +/* any L1 prim received from bts model */ +int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap); + +/* pcu (socket interface) sends us a data request primitive */ +int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len); + +/* call-back function for incoming RTP */ +void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, + unsigned int rtp_pl_len); + +/* channel control */ +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr); + +extern const struct value_string gsmtap_sapi_names[]; +extern struct gsmtap_inst *gsmtap; +extern uint32_t gsmtap_sapi_mask; +extern uint8_t gsmtap_sapi_acch; + +#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) + +#endif /* L1SAP_H */ -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:22 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:22 +0200 Subject: [PATCH 03/33] Add BCCH message to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-4-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This first part moves BCCH message primitives from osmo-bts-sysmo to common part. A new file "common/l1sap.c" is introduced to implement handling of layer 1 messages from/to BTS model. --- include/osmo-bts/bts_model.h | 2 + src/common/Makefile.am | 2 +- src/common/l1sap.c | 150 ++++++++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.c | 167 +++++++++++++++++++++++++++++++++++++++---- tests/stubs.c | 2 + 5 files changed, 310 insertions(+), 13 deletions(-) create mode 100644 src/common/l1sap.c diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h index 200d02d..f9b3f0b 100644 --- a/include/osmo-bts/bts_model.h +++ b/include/osmo-bts/bts_model.h @@ -48,4 +48,6 @@ int bts_model_oml_estab(struct gsm_bts *bts); int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm); +int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap); + #endif diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 10627e2..6de6214 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -7,4 +7,4 @@ libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ rsl.c vty.c paging.c measurement.c amr.c lchan.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \ - tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c + tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c l1sap.c diff --git a/src/common/l1sap.c b/src/common/l1sap.c new file mode 100644 index 0000000..f4f3246 --- /dev/null +++ b/src/common/l1sap.c @@ -0,0 +1,150 @@ +/* L1 SAP primitives */ + +/* (C) 2011 by Harald Welte + * (C) 2013 by Andreas Eversberg + * + * 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 + +static int l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap); + +static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = { + 0x03, 0x03, 0x01, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B +}; + +/* allocate a msgb containing a osmo_phsap_prim + optional l2 data + * in order to wrap femtobts header arround l2 data, there must be enough space + * in front and behind data pointer */ +struct msgb *l1sap_msgb_alloc(unsigned int l2_len) +{ + struct msgb *msg = msgb_alloc_headroom(512, 128, "l1sap_prim"); + + if (!msg) + return NULL; + + msg->l1h = msgb_put(msg, sizeof(struct osmo_phsap_prim)); + + return msg; +} + +/* PH-RTS-IND prim recevied from bts model */ +static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind) +{ + struct msgb *msg = l1sap->oph.msg; + struct gsm_time g_time; + uint8_t chan_nr, link_id; + uint8_t tn; + uint32_t fn; + uint8_t *p, *si; + + chan_nr = rts_ind->chan_nr; + link_id = rts_ind->link_id; + fn = rts_ind->fn; + tn = L1SAP_CHAN2TS(chan_nr); + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1P, "Rx PH-RTS.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id); + + /* reuse PH-RTS.ind for PH-DATA.req */ + if (!msg) { + LOGP(DL1P, LOGL_FATAL, "RTS without msg to be reused. Please " + "fix!\n"); + abort(); + } + msgb_trim(msg, sizeof(*l1sap)); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA, PRIM_OP_REQUEST, + msg); + msg->l2h = msg->l1h + sizeof(*l1sap); + + if (L1SAP_IS_CHAN_BCCH(chan_nr)) { + p = msgb_put(msg, GSM_MACBLOCK_LEN); + /* get them from bts->si_buf[] */ + si = bts_sysinfo_get(trx->bts, &g_time); + if (si) + memcpy(p, si, GSM_MACBLOCK_LEN); + else + memcpy(p, fill_frame, GSM_MACBLOCK_LEN); + } + + DEBUGP(DL1P, "Tx PH-DATA.req %02u/%02u/%02u chan_nr=%d link_id=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id); + + l1sap_down(trx, l1sap); + + /* don't free, because we forwarded data */ + return 1; +} + +/* any L1 prim received from bts model */ +int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) +{ + struct msgb *msg = l1sap->oph.msg; + int rc = 0; + + switch (OSMO_PRIM_HDR(&l1sap->oph)) { + case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): + rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); + break; + default: + LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n", + l1sap->oph.primitive, l1sap->oph.operation); + break; + } + + /* Special return value '1' means: do not free */ + if (rc != 1) + msgb_free(msg); + + return rc; +} + +/* any L1 prim sent to bts model */ +static int l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) +{ + return bts_model_l1sap_down(trx, l1sap); +} + diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 4b9ab3e..54e4761 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -415,8 +416,135 @@ static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = { 0x2B, 0x2B, 0x2B }; +static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, + struct osmo_phsap_prim *l1sap) +{ + struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx); + uint32_t u32Fn; + uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi; + uint8_t chan_nr, link_id; + GsmL1_Prim_t *l1p; + int len; + + if (!msg) { + LOGP(DL1C, LOGL_FATAL, "PH-DATA.req without msg. " + "Please fix!\n"); + abort(); + } + chan_nr = l1sap->u.data.chan_nr; + link_id = l1sap->u.data.link_id; + u32Fn = l1sap->u.data.fn; + u8Tn = L1SAP_CHAN2TS(chan_nr); + subCh = 0x1f; + if (L1SAP_IS_CHAN_BCCH(chan_nr)) { + sapi = GsmL1_Sapi_Bcch; + } else { + LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d " + "chan_nr %d link_id %d\n", l1sap->oph.primitive, + l1sap->oph.operation, chan_nr, link_id); + return -EINVAL; + } + + /* pull and trim msg to start of payload */ + msgb_pull(msg, sizeof(*l1sap)); + len = msg->len; + msgb_trim(msg, 0); + + /* convert l1sap message to GsmL1 primitive, keep payload */ + if (len) { + /* data request */ + GsmL1_PhDataReq_t *data_req; + GsmL1_MsgUnitParam_t *msu_param; + uint8_t *temp; + + /* wrap zeroed l1p structure arrount payload + * this must be done in three steps, since the actual + * payload is not at the end but inside the l1p structure. */ + temp = l1p->u.phDataReq.msgUnitParam.u8Buffer; + msgb_push(msg, temp - (uint8_t *)l1p); + memset(msg->data, 0, msg->len); + msgb_put(msg, len); + memset(msg->tail, 0, sizeof(*l1p) - msg->len); + msgb_put(msg, sizeof(*l1p) - msg->len); + msg->l1h = msg->data; + + l1p = msgb_l1prim(msg); + l1p->id = GsmL1_PrimId_PhDataReq; + data_req = &l1p->u.phDataReq; + data_req->hLayer1 = fl1->hLayer1; + data_req->u8Tn = u8Tn; + data_req->u32Fn = u32Fn; + data_req->sapi = sapi; + data_req->subCh = subCh; + data_req->u8BlockNbr = u8BlockNbr; + msu_param = &data_req->msgUnitParam; + msu_param->u8Size = len; + } else { + /* empty frame */ + GsmL1_PhEmptyFrameReq_t *empty_req; + + /* put l1p structure */ + msgb_put(msg, sizeof(*l1p)); + memset(msg->data, 0, msg->len); + msg->l1h = msg->data; + + l1p = msgb_l1prim(msg); + l1p->id = GsmL1_PrimId_PhEmptyFrameReq; + empty_req = &l1p->u.phEmptyFrameReq; + empty_req->hLayer1 = fl1->hLayer1; + empty_req->u8Tn = u8Tn; + empty_req->u32Fn = u32Fn; + empty_req->sapi = sapi; + empty_req->subCh = subCh; + empty_req->u8BlockNbr = u8BlockNbr; + } + + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], msg); + + return 0; +} + +/* primitive from common part */ +int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) +{ + struct msgb *msg = l1sap->oph.msg; + int rc = 0; + + switch (OSMO_PRIM_HDR(&l1sap->oph)) { + case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): + rc = ph_data_req(trx, msg, l1sap); + break; + default: + LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n", + l1sap->oph.primitive, l1sap->oph.operation); + rc = -EINVAL; + } + + if (rc) + msgb_free(msg); + return rc; +} + +static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, + GsmL1_Sapi_t sapi, GsmL1_SubCh_t subCh, + uint8_t u8Tn, uint32_t u32Fn) +{ + uint8_t cbits = 0; + switch (sapi) { + case GsmL1_Sapi_Bcch: + cbits = 0x10; + break; + default: + return 0; + } + + return (cbits << 3) | u8Tn; +} + static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, - GsmL1_PhReadyToSendInd_t *rts_ind) + GsmL1_PhReadyToSendInd_t *rts_ind, + struct msgb *l1p_msg) { struct gsm_bts_trx *trx = fl1->priv; struct gsm_bts *bts = trx->bts; @@ -427,9 +555,31 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, struct gsm_lchan *lchan; struct gsm_time g_time; uint32_t t3p; - uint8_t *si; struct osmo_phsap_prim pp; int rc; + struct osmo_phsap_prim *l1sap; + uint8_t chan_nr, link_id; + uint32_t fn; + + + /* check if primitive should be handled by common part */ + chan_nr = chan_nr_by_sapi(trx->ts[rts_ind->u8Tn].pchan, rts_ind->sapi, + rts_ind->subCh, rts_ind->u8Tn, rts_ind->u32Fn); + if (chan_nr) { + fn = rts_ind->u32Fn; + link_id = 0; + rc = msgb_trim(l1p_msg, sizeof(*l1sap)); + if (rc < 0) + MSGB_ABORT(l1p_msg, "No room for primitive\n"); + l1sap = msgb_l1sap_prim(l1p_msg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RTS, + PRIM_OP_INDICATION, l1p_msg); + l1sap->u.data.link_id = link_id; + l1sap->u.data.chan_nr = chan_nr; + l1sap->u.data.fn = fn; + + return l1sap_up(trx, l1sap); + } gsm_fn2gsmtime(&g_time, rts_ind->u32Fn); @@ -508,14 +658,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, msu_param->u8Buffer[2] = (g_time.t1 << 7) | (g_time.t2 << 2) | (t3p >> 1); msu_param->u8Buffer[3] = (t3p & 1); break; - case GsmL1_Sapi_Bcch: - /* get them from bts->si_buf[] */ - si = bts_sysinfo_get(bts, &g_time); - if (si) - memcpy(msu_param->u8Buffer, si, GSM_MACBLOCK_LEN); - else - memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); - break; case GsmL1_Sapi_Sacch: /* resolve the L2 entity using rts_ind->hLayer2 */ lchan = l1if_hLayer_to_lchan(trx, rts_ind->hLayer2); @@ -598,6 +740,7 @@ tx: /* transmit */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], resp_msg); + msgb_free(l1p_msg); return 0; empty_frame: @@ -952,8 +1095,8 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg) case GsmL1_PrimId_PhConnectInd: break; case GsmL1_PrimId_PhReadyToSendInd: - rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd); - break; + return handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, + msg); case GsmL1_PrimId_PhDataInd: rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); break; diff --git a/tests/stubs.c b/tests/stubs.c index 959f445..f270f22 100644 --- a/tests/stubs.c +++ b/tests/stubs.c @@ -42,6 +42,8 @@ int bts_model_rsl_chan_mod(struct gsm_lchan *lchan) { return 0; } void bts_model_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, unsigned int rtp_pl_len) {} +int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) +{ return 0; } int l1if_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:23 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:23 +0200 Subject: [PATCH 04/33] l1sap: Split ph_data_req() into smaller parts In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-5-git-send-email-laforge@gnumonks.org> ... in an effort to avoid introducing new/more spaghetti code Also, use offsetof() instead of pointer calculation to determine the start of GsmL1_Prim_t.u.phDataReq.msgUnitParam.u8Buffer --- src/osmo-bts-sysmo/l1_if.c | 72 ++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 54e4761..542e3ce 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1,6 +1,6 @@ /* Interface handler for Sysmocom L1 */ -/* (C) 2011 by Harald Welte +/* (C) 2011-2014 by Harald Welte * (C) 2014 by Holger Hans Peter Freyther * * All Rights Reserved @@ -416,6 +416,49 @@ static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = { 0x2B, 0x2B, 0x2B }; +/* fill PH-DATA.req from l1sap primitive */ +static GsmL1_PhDataReq_t * +data_req_from_l1sap(GsmL1_Prim_t *l1p, struct femtol1_hdl *fl1, + uint8_t tn, uint32_t fn, uint8_t sapi, uint8_t sub_ch, + uint8_t block_nr, uint8_t len) +{ + GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq; + + l1p->id = GsmL1_PrimId_PhDataReq; + + /* copy fields from PH-RSS.ind */ + data_req->hLayer1 = fl1->hLayer1; + data_req->u8Tn = tn; + data_req->u32Fn = fn; + data_req->sapi = sapi; + data_req->subCh = sub_ch; + data_req->u8BlockNbr = block_nr; + + data_req->msgUnitParam.u8Size = len; + + return data_req; +} + +/* fill PH-EMPTY_FRAME.req from l1sap primitive */ +static GsmL1_PhEmptyFrameReq_t * +empty_req_from_l1sap(GsmL1_Prim_t *l1p, struct femtol1_hdl *fl1, + uint8_t tn, uint32_t fn, uint8_t sapi, + uint8_t subch, uint8_t block_nr) +{ + GsmL1_PhEmptyFrameReq_t *empty_req = &l1p->u.phEmptyFrameReq; + + l1p->id = GsmL1_PrimId_PhEmptyFrameReq; + + empty_req->hLayer1 = fl1->hLayer1; + empty_req->u8Tn = tn; + empty_req->u32Fn = fn; + empty_req->sapi = sapi; + empty_req->subCh = subch; + empty_req->u8BlockNbr = block_nr; + + return empty_req; +} + static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, struct osmo_phsap_prim *l1sap) { @@ -453,15 +496,11 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, /* convert l1sap message to GsmL1 primitive, keep payload */ if (len) { /* data request */ - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - uint8_t *temp; /* wrap zeroed l1p structure arrount payload * this must be done in three steps, since the actual * payload is not at the end but inside the l1p structure. */ - temp = l1p->u.phDataReq.msgUnitParam.u8Buffer; - msgb_push(msg, temp - (uint8_t *)l1p); + msgb_push(msg, offsetof(GsmL1_Prim_t, u.phDataReq.msgUnitParam.u8Buffer)); memset(msg->data, 0, msg->len); msgb_put(msg, len); memset(msg->tail, 0, sizeof(*l1p) - msg->len); @@ -469,19 +508,9 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, msg->l1h = msg->data; l1p = msgb_l1prim(msg); - l1p->id = GsmL1_PrimId_PhDataReq; - data_req = &l1p->u.phDataReq; - data_req->hLayer1 = fl1->hLayer1; - data_req->u8Tn = u8Tn; - data_req->u32Fn = u32Fn; - data_req->sapi = sapi; - data_req->subCh = subCh; - data_req->u8BlockNbr = u8BlockNbr; - msu_param = &data_req->msgUnitParam; - msu_param->u8Size = len; + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len); } else { /* empty frame */ - GsmL1_PhEmptyFrameReq_t *empty_req; /* put l1p structure */ msgb_put(msg, sizeof(*l1p)); @@ -489,14 +518,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, msg->l1h = msg->data; l1p = msgb_l1prim(msg); - l1p->id = GsmL1_PrimId_PhEmptyFrameReq; - empty_req = &l1p->u.phEmptyFrameReq; - empty_req->hLayer1 = fl1->hLayer1; - empty_req->u8Tn = u8Tn; - empty_req->u32Fn = u32Fn; - empty_req->sapi = sapi; - empty_req->subCh = subCh; - empty_req->u8BlockNbr = u8BlockNbr; + empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } /* send message to DSP's queue */ -- 2.1.0 From holger at freyther.de Thu Aug 28 11:54:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 28 Aug 2014 13:54:38 +0200 Subject: [PATCH 04/33] l1sap: Split ph_data_req() into smaller parts In-Reply-To: <1409176492-13269-5-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <1409176492-13269-5-git-send-email-laforge@gnumonks.org> Message-ID: <20140828115438.GB3508@xiaoyu.lan> On Wed, Aug 27, 2014 at 11:54:23PM +0200, Harald Welte wrote: > ... in an effort to avoid introducing new/more spaghetti code thanks! From laforge at gnumonks.org Thu Aug 28 13:23:49 2014 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 28 Aug 2014 15:23:49 +0200 Subject: [PATCH 04/33] l1sap: Split ph_data_req() into smaller parts In-Reply-To: <20140828115438.GB3508@xiaoyu.lan> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <1409176492-13269-5-git-send-email-laforge@gnumonks.org> <20140828115438.GB3508@xiaoyu.lan> Message-ID: <20140828132349.GB12087@nataraja> On Thu, Aug 28, 2014 at 01:54:38PM +0200, Holger Hans Peter Freyther wrote: > On Wed, Aug 27, 2014 at 11:54:23PM +0200, Harald Welte wrote: > > ... in an effort to avoid introducing new/more spaghetti code > > thanks! The other obvious candidate is the (now) long section at the beginning of ph_data_req() that determines sapi/subch/blocknr from the link_id and channel number. However, given that all major patches in the series touches the code, I decided to postpone that split until the series is merged. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From laforge at gnumonks.org Wed Aug 27 21:54:24 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:24 +0200 Subject: [PATCH 05/33] Add RACH message to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-6-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves RACH message primitives from osmo-bts-sysmo to common part. --- src/common/l1sap.c | 69 +++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.c | 97 +++++++++++++++------------------------------- 2 files changed, 101 insertions(+), 65 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index f4f3246..dfc81a4 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -119,6 +119,72 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, return 1; } +static int check_acc_delay(struct ph_rach_ind_param *rach_ind, + struct gsm_bts_role_bts *btsb, uint8_t *acc_delay) +{ + *acc_delay = rach_ind->acc_delay; + return *acc_delay <= btsb->max_ta; +} + +/* special case where handover RACH is detected */ +static int l1sap_handover_rach(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind) +{ + struct gsm_lchan *lchan; + uint8_t chan_nr; + uint8_t tn, ss; + + chan_nr = rach_ind->chan_nr; + tn = L1SAP_CHAN2TS(chan_nr); + ss = l1sap_chan2ss(chan_nr); + lchan = &trx->ts[tn].lchan[ss]; + + handover_rach(lchan, rach_ind->ra, rach_ind->acc_delay); + + /* must return 0, so in case of msg at l1sap, it will be freed */ + return 0; +} + +/* RACH received from bts model */ +static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind) +{ + struct gsm_bts *bts = trx->bts; + struct gsm_bts_role_bts *btsb = bts->role; + struct lapdm_channel *lc; + uint8_t acc_delay; + + DEBUGP(DL1P, "Rx PH-RA.ind"); + + lc = &trx->ts[0].lchan[4].lapdm_ch; + + /* check for under/overflow / sign */ + if (!check_acc_delay(rach_ind, btsb, &acc_delay)) { + LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", + acc_delay, btsb->max_ta); + return 0; + } + + /* check for handover rach */ + if (trx != bts->c0 && rach_ind->chan_nr != 0x88) + return l1sap_handover_rach(trx, l1sap, rach_ind); + + /* check for packet access */ + if (trx == bts->c0 + && L1SAP_IS_PACKET_RACH(rach_ind->ra)) { + LOGP(DL1P, LOGL_INFO, "RACH for packet access\n"); + pcu_tx_rach_ind(bts, rach_ind->acc_delay << 2, + rach_ind->ra, rach_ind->fn); + return 0; + } + + LOGP(DL1P, LOGL_INFO, "RACH for RR access (toa=%d, ra=%d)\n", + rach_ind->acc_delay, rach_ind->ra); + lapdm_phsap_up(&l1sap->oph, &lc->lapdm_dcch); + + return 0; +} + /* any L1 prim received from bts model */ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) { @@ -129,6 +195,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; + case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION): + rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind); + break; default: LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n", l1sap->oph.primitive, l1sap->oph.operation); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 542e3ce..c28e467 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1015,91 +1015,58 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i return rc; } -static int check_acc_delay(GsmL1_PhRaInd_t *ra_ind, struct gsm_bts_role_bts *btsb, - uint8_t *acc_delay) -{ - if (ra_ind->measParam.i16BurstTiming < 0) - *acc_delay = 0; - else - *acc_delay = ra_ind->measParam.i16BurstTiming >> 2; - return *acc_delay <= btsb->max_ta; -} - -static int handle_handover(struct gsm_lchan *lchan, struct gsm_bts_role_bts *btsb, - GsmL1_PhRaInd_t *ra_ind) -{ - uint8_t acc_delay; - if (!check_acc_delay(ra_ind, btsb, &acc_delay)) { - LOGP(DHO, LOGL_INFO, "%s ignoring RACH request %u > max_ta(%u)\n", - gsm_lchan_name(lchan), acc_delay, btsb->max_ta); - return 0; - } - - handover_rach(lchan, ra_ind->msgUnitParam.u8Buffer[0], acc_delay); - return 0; -} - -static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind) +static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, + struct msgb *l1p_msg) { struct gsm_bts_trx *trx = fl1->priv; struct gsm_bts *bts = trx->bts; struct gsm_bts_role_bts *btsb = bts->role; struct gsm_lchan *lchan; - struct osmo_phsap_prim pp; - struct lapdm_channel *lc; - uint8_t acc_delay; + struct osmo_phsap_prim *l1sap; + uint32_t fn; + uint8_t ra, acc_delay = 0; + int rc; /* increment number of busy RACH slots, if required */ if (trx == bts->c0 && ra_ind->measParam.fRssi >= btsb->load.rach.busy_thresh) btsb->load.rach.busy++; - if (ra_ind->measParam.fLinkQuality < fl1->min_qual_rach) + if (ra_ind->measParam.fLinkQuality < fl1->min_qual_rach) { + msgb_free(l1p_msg); return 0; + } - /* - * Check if this is a handover - */ - lchan = l1if_hLayer_to_lchan(trx, ra_ind->hLayer2); - if (lchan && lchan->ho.active == HANDOVER_ENABLED) - return handle_handover(lchan, btsb, ra_ind); + if (ra_ind->measParam.i16BurstTiming > 0) + acc_delay = ra_ind->measParam.i16BurstTiming >> 2; - /* increment number of RACH slots with valid RACH burst */ - if (trx == bts->c0) + /* increment number of RACH slots with valid non-handover RACH burst */ + lchan = l1if_hLayer_to_lchan(trx, ra_ind->hLayer2); + if (trx == bts->c0 && !(lchan && lchan->ho.active == HANDOVER_ENABLED)) btsb->load.rach.access++; - DEBUGP(DL1C, "Rx PH-RA.ind"); dump_meas_res(LOGL_DEBUG, &ra_ind->measParam); - lc = get_lapdm_chan_by_hl2(fl1->priv, ra_ind->hLayer2); - if (!lc) { - LOGP(DL1C, LOGL_ERROR, "unable to resolve LAPD channel by hLayer2\n"); - return -ENODEV; - } - - /* check for under/overflow / sign */ - if (!check_acc_delay(ra_ind, btsb, &acc_delay)) { - LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", - acc_delay, btsb->max_ta); + if (ra_ind->msgUnitParam.u8Size != 1) { + LOGP(DL1C, LOGL_ERROR, "PH-RACH-INDICATION has %d bits\n", + ra_ind->sapi); + msgb_free(l1p_msg); return 0; } - /* check for packet access */ - if (trx == bts->c0 - && (ra_ind->msgUnitParam.u8Buffer[0] & 0xf0) == 0x70) { - LOGP(DL1C, LOGL_INFO, "RACH for packet access\n"); - return pcu_tx_rach_ind(bts, ra_ind->measParam.i16BurstTiming, - ra_ind->msgUnitParam.u8Buffer[0], ra_ind->u32Fn); - } - - osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RACH, - PRIM_OP_INDICATION, NULL); - - pp.u.rach_ind.ra = ra_ind->msgUnitParam.u8Buffer[0]; - pp.u.rach_ind.fn = ra_ind->u32Fn; - pp.u.rach_ind.acc_delay = acc_delay; - - return lapdm_phsap_up(&pp.oph, &lc->lapdm_dcch); + fn = ra_ind->u32Fn; + ra = ra_ind->msgUnitParam.u8Buffer[0]; + rc = msgb_trim(l1p_msg, sizeof(*l1sap)); + if (rc < 0) + MSGB_ABORT(l1p_msg, "No room for primitive data\n"); + l1sap = msgb_l1sap_prim(l1p_msg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION, + l1p_msg); + l1sap->u.rach_ind.ra = ra; + l1sap->u.rach_ind.acc_delay = acc_delay; + l1sap->u.rach_ind.fn = fn; + + return l1sap_up(trx, l1sap); } /* handle any random indication from the L1 */ @@ -1123,7 +1090,7 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg) rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); break; case GsmL1_PrimId_PhRaInd: - rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd); + return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); break; default: break; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:25 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:25 +0200 Subject: [PATCH 06/33] l1sap: Use L1SAP_IS_CHAN_RACH instead of magic number 0x88 In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-7-git-send-email-laforge@gnumonks.org> --- src/common/l1sap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index dfc81a4..5cb72b6 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -166,7 +166,7 @@ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, } /* check for handover rach */ - if (trx != bts->c0 && rach_ind->chan_nr != 0x88) + if (trx != bts->c0 && !L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) return l1sap_handover_rach(trx, l1sap, rach_ind); /* check for packet access */ -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:26 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:26 +0200 Subject: [PATCH 07/33] l1sap: fix coding style In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-8-git-send-email-laforge@gnumonks.org> --- src/common/l1sap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 5cb72b6..c788a79 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -170,8 +170,7 @@ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, return l1sap_handover_rach(trx, l1sap, rach_ind); /* check for packet access */ - if (trx == bts->c0 - && L1SAP_IS_PACKET_RACH(rach_ind->ra)) { + if (trx == bts->c0 && L1SAP_IS_PACKET_RACH(rach_ind->ra)) { LOGP(DL1P, LOGL_INFO, "RACH for packet access\n"); pcu_tx_rach_ind(bts, rach_ind->acc_delay << 2, rach_ind->ra, rach_ind->fn); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:27 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:27 +0200 Subject: [PATCH 08/33] l1sap: fix missing include file and resulting compiler warning In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-9-git-send-email-laforge@gnumonks.org> --- src/common/l1sap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index c788a79..a4db8fb 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -44,6 +44,7 @@ #include #include #include +#include static int l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:28 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:28 +0200 Subject: [PATCH 09/33] l1sap: RACH: Detect hand-over even on TRX0 In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-10-git-send-email-laforge@gnumonks.org> I don't understand why we would detect handover only on TRX1-n, but not on TRX0. It is perfectly valid for a handover to occur on TRX0. --- src/common/l1sap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index a4db8fb..2dedf02 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -167,7 +167,7 @@ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, } /* check for handover rach */ - if (trx != bts->c0 && !L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) + if (!L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) return l1sap_handover_rach(trx, l1sap, rach_ind); /* check for packet access */ -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:29 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:29 +0200 Subject: [PATCH 10/33] l1sap: correctly set chan_nr on PRIM_PH_RACH / INDICATION In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-11-git-send-email-laforge@gnumonks.org> In case of a RACH INDICATION on CCCH, we need to set CHAN_NR to 0x88 (RSL_CHAN_RACH). In other cases, chan_nr needs to reflect the actual logical channel (TCH/SDCCH) on whcih the handover happened. --- src/osmo-bts-sysmo/l1_if.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index c28e467..9c6817c 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1065,6 +1065,11 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, l1sap->u.rach_ind.ra = ra; l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; + if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || + lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) + l1sap->u.rach_ind.chan_nr = 0x88; + else + l1sap->u.rach_ind.chan_nr = gsm_lchan2chan_nr(lchan); return l1sap_up(trx, l1sap); } -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:30 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:30 +0200 Subject: [PATCH 11/33] l1sap: sysmobts: remove obsolete get_lapdm_chan_by_hl2() In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-12-git-send-email-laforge@gnumonks.org> --- src/osmo-bts-sysmo/l1_if.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 9c6817c..d169b27 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -320,19 +320,6 @@ empty_req_from_rts_ind(GsmL1_Prim_t *l1p, return empty_req; } -/* obtain a ptr to the lapdm_channel for a given hLayer2 */ -static struct lapdm_channel * -get_lapdm_chan_by_hl2(struct gsm_bts_trx *trx, uint32_t hLayer2) -{ - struct gsm_lchan *lchan; - - lchan = l1if_hLayer_to_lchan(trx, hLayer2); - if (!lchan) - return NULL; - - return &lchan->lapdm_ch; -} - /* check if the message is a GSM48_MT_RR_CIPH_M_CMD, and if yes, enable * uni-directional de-cryption on the uplink. We need this ugly layering * violation as we have no way of passing down L3 metadata (RSL CIPHERING CMD) -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:31 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:31 +0200 Subject: [PATCH 12/33] Add PCH/AGCH message to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-13-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves PCH and AGCH message primitives from osmo-bts-sysmo to common part. --- src/common/l1sap.c | 8 ++++++++ src/osmo-bts-sysmo/l1_if.c | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 2dedf02..da4cc48 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -79,6 +79,7 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, uint8_t tn; uint32_t fn; uint8_t *p, *si; + int rc; chan_nr = rts_ind->chan_nr; link_id = rts_ind->link_id; @@ -109,6 +110,13 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, memcpy(p, si, GSM_MACBLOCK_LEN); else memcpy(p, fill_frame, GSM_MACBLOCK_LEN); + } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { + p = msgb_put(msg, GSM_MACBLOCK_LEN); + /* if CCCH block is 0, it is AGCH */ + rc = bts_ccch_copy_msg(trx->bts, p, &g_time, + (L1SAP_FN2CCCHBLOCK(fn) < 1)); + if (rc <= 0) + memcpy(p, fill_frame, GSM_MACBLOCK_LEN); } DEBUGP(DL1P, "Tx PH-DATA.req %02u/%02u/%02u chan_nr=%d link_id=%d\n", diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index d169b27..a3fd64e 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -468,6 +468,14 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, subCh = 0x1f; if (L1SAP_IS_CHAN_BCCH(chan_nr)) { sapi = GsmL1_Sapi_Bcch; + } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { + /* The sapi depends on DSP configuration, not + * on the actual SYSTEM INFORMATION 3. */ + u8BlockNbr = L1SAP_FN2CCCHBLOCK(u32Fn); + if (u8BlockNbr >= 1) + sapi = GsmL1_Sapi_Pch; + else + sapi = GsmL1_Sapi_Agch; } else { LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d " "chan_nr %d link_id %d\n", l1sap->oph.primitive, @@ -544,6 +552,10 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, case GsmL1_Sapi_Bcch: cbits = 0x10; break; + case GsmL1_Sapi_Agch: + case GsmL1_Sapi_Pch: + cbits = 0x12; + break; default: return 0; } @@ -707,13 +719,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, msgb_free(pp.oph.msg); } break; - case GsmL1_Sapi_Agch: - case GsmL1_Sapi_Pch: - rc = bts_ccch_copy_msg(bts, msu_param->u8Buffer, &g_time, - rts_ind->sapi == GsmL1_Sapi_Agch); - if (rc <= 0) - memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); - break; case GsmL1_Sapi_TchF: case GsmL1_Sapi_TchH: /* only hit in case we have a RTP underflow, as real TCH -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:32 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:32 +0200 Subject: [PATCH 13/33] l1sap: Add a warning about assuming BS_AG_BLKS_RES=1 In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-14-git-send-email-laforge@gnumonks.org> This is a regression of the code compared to the existing sysmoBTS code, where the L1 tells us whether its AGCH or PCH. However, it was not used even in the old code, so we can afford to simply put a #warning here. --- src/common/l1sap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index da4cc48..12be383 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -112,6 +112,7 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, memcpy(p, fill_frame, GSM_MACBLOCK_LEN); } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { p = msgb_put(msg, GSM_MACBLOCK_LEN); +#warning "TODO: Yet another assumption that BS_AG_BLKS_RES=1" /* if CCCH block is 0, it is AGCH */ rc = bts_ccch_copy_msg(trx->bts, p, &g_time, (L1SAP_FN2CCCHBLOCK(fn) < 1)); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:33 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:33 +0200 Subject: [PATCH 14/33] Add PDCH messages to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-15-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves PDTCH, PACCH and PTCCH message primitives from osmo-bts-sysmo to common part. --- src/common/l1sap.c | 90 +++++++++++++++++++++++++++ src/common/pcu_sock.c | 7 +-- src/osmo-bts-sysmo/l1_if.c | 152 ++++++++++++++++++++++++--------------------- 3 files changed, 172 insertions(+), 77 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 12be383..633a5a5 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -91,6 +91,19 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, DEBUGP(DL1P, "Rx PH-RTS.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n", g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id); + if (trx->ts[tn].pchan == GSM_PCHAN_PDCH) { + if (L1SAP_IS_PTCCH(rts_ind->fn)) { + pcu_tx_rts_req(&trx->ts[tn], 1, fn, 1 /* ARFCN */, + L1SAP_FN2PTCCHBLOCK(fn)); + + return 0; + } + pcu_tx_rts_req(&trx->ts[tn], 0, fn, 0 /* ARFCN */, + L1SAP_FN2MACBLOCK(fn)); + + return 0; + } + /* reuse PH-RTS.ind for PH-DATA.req */ if (!msg) { LOGP(DL1P, LOGL_FATAL, "RTS without msg to be reused. Please " @@ -155,6 +168,54 @@ static int l1sap_handover_rach(struct gsm_bts_trx *trx, return 0; } +/* DATA received from bts model */ +static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) +{ + struct msgb *msg = l1sap->oph.msg; + struct gsm_time g_time; + uint8_t *data = msg->l2h; + int len = msgb_l2len(msg); + uint8_t chan_nr, link_id; + uint8_t tn, ss; + uint32_t fn; + int8_t rssi; + + rssi = data_ind->rssi; + chan_nr = data_ind->chan_nr; + link_id = data_ind->link_id; + fn = data_ind->fn; + tn = L1SAP_CHAN2TS(chan_nr); + ss = l1sap_chan2ss(chan_nr); + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1P, "Rx PH-DATA.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id); + + if (trx->ts[tn].pchan == GSM_PCHAN_PDCH) { + if (len == 0) + return -EINVAL; + if (L1SAP_IS_PTCCH(fn)) { + pcu_tx_data_ind(&trx->ts[tn], 1, fn, + 0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn), + data, len, rssi); + + return 0; + } + /* drop incomplete UL block */ + if (data[0] != 7) + return 0; + /* PDTCH / PACCH frame handling */ + pcu_tx_data_ind(&trx->ts[tn], 0, fn, 0 /* ARFCN */, + L1SAP_FN2MACBLOCK(fn), data + 1, len - 1, rssi); + + return 0; + } + + return 0; +} + /* RACH received from bts model */ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind) @@ -204,6 +265,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; + case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_INDICATION): + rc = l1sap_ph_data_ind(trx, l1sap, &l1sap->u.data); + break; case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION): rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind); break; @@ -226,3 +290,29 @@ static int l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) return bts_model_l1sap_down(trx, l1sap); } +/* pcu (socket interface) sends us a data request primitive */ +int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) +{ + struct msgb *msg; + struct osmo_phsap_prim *l1sap; + struct gsm_time g_time; + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1P, "TX packet data %02u/%02u/%02u is_ptcch=%d trx=%d ts=%d " + "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, + g_time.t3, is_ptcch, ts->trx->nr, ts->nr, block_nr, arfcn, len); + + msg = l1sap_msgb_alloc(len); + l1sap = msgb_l1sap_prim(msg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA, PRIM_OP_REQUEST, + msg); + l1sap->u.data.chan_nr = 0x08 | ts->nr; + l1sap->u.data.link_id = 0x00; + l1sap->u.data.fn = fn; + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + + return l1sap_down(ts->trx, l1sap); +} diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index a978e46..515993e 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -40,6 +40,7 @@ #include #include #include +#include uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); @@ -57,10 +58,6 @@ static const char *sapi_string[] = { [PCU_IF_SAPI_PTCCH] = "PTCCH", }; -/* FIXME: common l1if include ? */ -int l1if_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, - uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len); - static int pcu_sock_send(struct gsm_network *net, struct msgb *msg); /* FIXME: move this to libosmocore */ int osmo_unixsock_listen(struct osmo_fd *bfd, int type, const char *path); @@ -512,7 +509,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, } ts = &trx->ts[data_req->ts_nr]; is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH); - rc = l1if_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn, + rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn, data_req->block_nr, data_req->data, data_req->len); break; default: diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index a3fd64e..d4861e2 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -466,7 +466,17 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, u32Fn = l1sap->u.data.fn; u8Tn = L1SAP_CHAN2TS(chan_nr); subCh = 0x1f; - if (L1SAP_IS_CHAN_BCCH(chan_nr)) { + if (L1SAP_IS_CHAN_TCHF(chan_nr)) { + if (trx->ts[u8Tn].pchan == GSM_PCHAN_PDCH) { + if (L1SAP_IS_PTCCH(u32Fn)) { + sapi = GsmL1_Sapi_Ptcch; + u8BlockNbr = L1SAP_FN2PTCCHBLOCK(u32Fn); + } else { + sapi = GsmL1_Sapi_Pdtch; + u8BlockNbr = L1SAP_FN2MACBLOCK(u32Fn); + } + } + } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) { sapi = GsmL1_Sapi_Bcch; } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { /* The sapi depends on DSP configuration, not @@ -556,6 +566,35 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, case GsmL1_Sapi_Pch: cbits = 0x12; break; + case GsmL1_Sapi_Pdtch: + case GsmL1_Sapi_Pacch: + switch(pchan) { + case GSM_PCHAN_PDCH: + cbits = 0x01; + break; + default: + LOGP(DL1C, LOGL_ERROR, "PDTCH for pchan %d?\n", + pchan); + return 0; + } + break; + case GsmL1_Sapi_Ptcch: + if (!L1SAP_IS_PTCCH(u32Fn)) { + LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame " + "number other than 12, got it at %u (%u). " + "Please fix!\n", u32Fn % 52, u32Fn); + abort(); + } + switch(pchan) { + case GSM_PCHAN_PDCH: + cbits = 0x01; + break; + default: + LOGP(DL1C, LOGL_ERROR, "PTCCH for pchan %d?\n", + pchan); + return 0; + } + break; default: return 0; } @@ -648,13 +687,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, /* actually transmit it */ goto tx; break; - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - return pcu_tx_rts_req(&trx->ts[rts_ind->u8Tn], 0, - rts_ind->u32Fn, rts_ind->u16Arfcn, rts_ind->u8BlockNbr); - case GsmL1_Sapi_Ptcch: - return pcu_tx_rts_req(&trx->ts[rts_ind->u8Tn], 1, - rts_ind->u32Fn, rts_ind->u16Arfcn, rts_ind->u8BlockNbr); default: break; } @@ -886,6 +918,10 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i struct gsm_lchan *lchan; struct lapdm_entity *le; struct msgb *msg; + uint8_t chan_nr, link_id; + struct osmo_phsap_prim *l1sap; + uint32_t fn; + uint8_t *data, len; int rc = 0; ul_to_gsmtap(fl1, l1p_msg); @@ -895,14 +931,22 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i LOGP(DL1C, LOGL_ERROR, "unable to resolve lchan by hLayer2 for 0x%x\n", data_ind->hLayer2); + msgb_free(l1p_msg); return -ENODEV; } + chan_nr = chan_nr_by_sapi(trx->ts[data_ind->u8Tn].pchan, data_ind->sapi, + data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn); + fn = data_ind->u32Fn; + link_id = (data_ind->sapi == GsmL1_Sapi_Sacch) ? 0x40 : 0x00; + process_meas_res(lchan, &data_ind->measParam); if (data_ind->measParam.fLinkQuality < fl1->min_qual_norm - && data_ind->msgUnitParam.u8Size != 0) + && data_ind->msgUnitParam.u8Size != 0) { + msgb_free(l1p_msg); return 0; + } DEBUGP(DL1C, "Rx PH-DATA.ind %s (hL2 %08x): %s", get_value_string(femtobts_l1sapi_names, data_ind->sapi), @@ -973,27 +1017,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i break; case GsmL1_Sapi_Pdtch: case GsmL1_Sapi_Pacch: - /* drop incomplete UL block */ - if (!data_ind->msgUnitParam.u8Size - || data_ind->msgUnitParam.u8Buffer[0] - != GsmL1_PdtchPlType_Full) - break; - /* PDTCH / PACCH frame handling */ - rc = pcu_tx_data_ind(&trx->ts[data_ind->u8Tn], 0, - data_ind->u32Fn, data_ind->u16Arfcn, - data_ind->u8BlockNbr, - data_ind->msgUnitParam.u8Buffer + 1, - data_ind->msgUnitParam.u8Size - 1, - (int8_t) (data_ind->measParam.fRssi)); - break; case GsmL1_Sapi_Ptcch: - /* PTCCH frame handling */ - rc = pcu_tx_data_ind(&trx->ts[data_ind->u8Tn], 1, - data_ind->u32Fn, data_ind->u16Arfcn, - data_ind->u8BlockNbr, - data_ind->msgUnitParam.u8Buffer, - data_ind->msgUnitParam.u8Size, - (int8_t) (data_ind->measParam.fRssi)); break; case GsmL1_Sapi_Idle: /* nothing to send */ @@ -1004,7 +1028,32 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i break; } - return rc; + if (!chan_nr) { + msgb_free(l1p_msg); + return rc; + } + + /* get data pointer and length */ + data = data_ind->msgUnitParam.u8Buffer; + len = data_ind->msgUnitParam.u8Size; + /* pull lower header part before data */ + msgb_pull(l1p_msg, data - l1p_msg->data); + /* trim remaining data to it's size, to get rid of upper header part */ + rc = msgb_trim(l1p_msg, len); + if (rc < 0) + MSGB_ABORT(l1p_msg, "No room for primitive data\n"); + l1p_msg->l2h = l1p_msg->data; + /* push new l1 header */ + l1p_msg->l1h = msgb_push(l1p_msg, sizeof(*l1sap)); + /* fill header */ + l1sap = msgb_l1sap_prim(l1p_msg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA, + PRIM_OP_INDICATION, l1p_msg); + l1sap->u.data.link_id = link_id; + l1sap->u.data.chan_nr = chan_nr; + l1sap->u.data.fn = fn; + + return l1sap_up(trx, l1sap); } static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, @@ -1084,8 +1133,7 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg) return handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd, msg); case GsmL1_PrimId_PhDataInd: - rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); - break; + return handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); case GsmL1_PrimId_PhRaInd: return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg); break; @@ -1538,46 +1586,6 @@ int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags) return osmo_wqueue_enqueue(&hdl->write_q[MQ_SYS_WRITE], msg); } -/* send packet data request to L1 */ -int l1if_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, - uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) -{ - struct gsm_bts_trx *trx = ts->trx; - struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - 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(DL1P, "TX packet data %02u/%02u/%02u is_ptcch=%d trx=%d ts=%d " - "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, - g_time.t3, is_ptcch, ts->trx->nr, ts->nr, 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->nr; - data_req->u32Fn = fn; - msu_param = &data_req->msgUnitParam; - msu_param->u8Size = len; - memcpy(msu_param->u8Buffer, data, len); - - tx_to_gsmtap(fl1h, msg); - - /* transmit */ - osmo_wqueue_enqueue(&fl1h->write_q[MQ_L1_WRITE], msg); - - return 0; -} - /* get those femtol1_hdl.hw_info elements that sre in EEPROM */ static int get_hwinfo_eeprom(struct femtol1_hdl *fl1h) { -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:34 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:34 +0200 Subject: [PATCH 15/33] l1sap: additional comments explaining l1sap changes in l1_if.c In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-16-git-send-email-laforge@gnumonks.org> --- src/osmo-bts-sysmo/l1_if.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index d4861e2..03e8a56 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -599,6 +599,7 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, return 0; } + /* not reached due to default case above */ return (cbits << 3) | u8Tn; } @@ -1029,10 +1030,13 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i } if (!chan_nr) { + /* message was handled by old code, not by L1SAP */ msgb_free(l1p_msg); return rc; } + /* if we proceed to this point, the message has to be handled via L1SAP */ + /* get data pointer and length */ data = data_ind->msgUnitParam.u8Buffer; len = data_ind->msgUnitParam.u8Size; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:35 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:35 +0200 Subject: [PATCH 16/33] Add TIME (MPH_INFO) IND messages to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-17-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves GSM time handling from osmo-bts-sysmo part to common part. --- include/osmo-bts/gsm_data.h | 1 + src/common/l1sap.c | 50 ++++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.c | 65 +++++++++++++++++++-------------------------- 3 files changed, 78 insertions(+), 38 deletions(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 5e0af77..c6866a3 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -80,6 +80,7 @@ struct gsm_bts_role_bts { struct { uint8_t tc4_ctr; } si; + struct gsm_time gsm_time; uint8_t radio_link_timeout; /* used by the sysmoBTS to adjust band */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 633a5a5..6cb636d 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -69,6 +69,53 @@ struct msgb *l1sap_msgb_alloc(unsigned int l2_len) return msg; } +/* time information received from bts model */ +static int l1sap_info_time_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_time_ind_param *info_time_ind) +{ + struct gsm_bts *bts = trx->bts; + struct gsm_bts_role_bts *btsb = bts->role; + + DEBUGP(DL1P, "MPH_INFO time ind %u\n", info_time_ind->fn); + + /* Update our data structures with the current GSM time */ + gsm_fn2gsmtime(&btsb->gsm_time, info_time_ind->fn); + + /* Update time on PCU interface */ + pcu_tx_time_ind(info_time_ind->fn); + + /* check if the measurement period of some lchan has ended + * and pre-compute the respective measurement */ + trx_meas_check_compute(trx, info_time_ind->fn - 1); + + /* increment 'total' for every possible rach */ + if (bts->c0->ts[0].pchan != GSM_PCHAN_CCCH_SDCCH4 + || (info_time_ind->fn % 51) < 27) + btsb->load.rach.total++; + + return 0; +} + +/* any L1 MPH_INFO indication prim recevied from bts model */ +static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct mph_info_param *info) +{ + int rc = 0; + + switch (info->type) { + case PRIM_INFO_TIME: + rc = l1sap_info_time_ind(trx, l1sap, &info->u.time_ind); + break; + default: + LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO ind type %d\n", + info->type); + break; + } + + return rc; +} + /* PH-RTS-IND prim recevied from bts model */ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind) @@ -262,6 +309,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) int rc = 0; switch (OSMO_PRIM_HDR(&l1sap->oph)) { + case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_INDICATION): + rc = l1sap_mph_info_ind(trx, l1sap, &l1sap->u.info); + break; case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 03e8a56..59a30f2 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -553,6 +553,33 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) return rc; } +static int handle_mph_time_ind(struct femtol1_hdl *fl1, + GsmL1_MphTimeInd_t *time_ind) +{ + struct gsm_bts_trx *trx = fl1->priv; + struct gsm_bts *bts = trx->bts; + struct osmo_phsap_prim l1sap; + uint32_t fn; + + /* increment the primitive count for the alive timer */ + fl1->alive_prim_cnt++; + + /* ignore every time indication, except for c0 */ + if (trx != bts->c0) { + return 0; + } + + fn = time_ind->u32Fn; + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, + PRIM_OP_INDICATION, NULL); + l1sap.u.info.type = PRIM_INFO_TIME; + l1sap.u.info.u.time_ind.fn = fn; + + return l1sap_up(trx, &l1sap); +} + static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, GsmL1_Sapi_t sapi, GsmL1_SubCh_t subCh, uint8_t u8Tn, uint32_t u32Fn) @@ -797,44 +824,6 @@ empty_frame: goto tx; } -static int handle_mph_time_ind(struct femtol1_hdl *fl1, - GsmL1_MphTimeInd_t *time_ind) -{ - struct gsm_bts_trx *trx = fl1->priv; - struct gsm_bts *bts = trx->bts; - struct gsm_bts_role_bts *btsb = bts->role; - - int frames_expired = time_ind->u32Fn - fl1->gsm_time.fn; - - /* update time on PCU interface */ - pcu_tx_time_ind(time_ind->u32Fn); - - /* Update our data structures with the current GSM time */ - gsm_fn2gsmtime(&fl1->gsm_time, time_ind->u32Fn); - - /* check if the measurement period of some lchan has ended - * and pre-compute the respective measurement */ - trx_meas_check_compute(fl1->priv, time_ind->u32Fn -1); - - /* increment the primitive count for the alive timer */ - fl1->alive_prim_cnt++; - - /* increment number of RACH slots that have passed by since the - * last time indication */ - if (trx == bts->c0) { - unsigned int num_rach_per_frame; - /* 27 / 51 taken from TS 05.01 Figure 3 */ - if (bts->c0->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4) - num_rach_per_frame = 27; - else - num_rach_per_frame = 51; - - btsb->load.rach.total += frames_expired * num_rach_per_frame; - } - - return 0; -} - /* determine LAPDm entity inside LAPDm channel for given L1 sapi */ static struct lapdm_entity *le_by_l1_sapi(struct lapdm_channel *lc, GsmL1_Sapi_t sapi) { -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:36 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:36 +0200 Subject: [PATCH 17/33] l1sap: Re-introduce more correct RACH slot counting In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-18-git-send-email-laforge@gnumonks.org> The original code handled both the fact where a TIME indication would be missed (and thus the frame number be higher than previous + 1), as well as the two cases for combined / non-combined CCCH. The L1SAP code removed some of those bits, which I'm re-introducing here. --- src/common/l1sap.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 6cb636d..9bbbdf3 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -77,6 +77,8 @@ static int l1sap_info_time_ind(struct gsm_bts_trx *trx, struct gsm_bts *bts = trx->bts; struct gsm_bts_role_bts *btsb = bts->role; + int frames_expired = info_time_ind->fn - btsb->gsm_time.fn; + DEBUGP(DL1P, "MPH_INFO time ind %u\n", info_time_ind->fn); /* Update our data structures with the current GSM time */ @@ -89,10 +91,18 @@ static int l1sap_info_time_ind(struct gsm_bts_trx *trx, * and pre-compute the respective measurement */ trx_meas_check_compute(trx, info_time_ind->fn - 1); - /* increment 'total' for every possible rach */ - if (bts->c0->ts[0].pchan != GSM_PCHAN_CCCH_SDCCH4 - || (info_time_ind->fn % 51) < 27) - btsb->load.rach.total++; + /* increment number of RACH slots that have passed by since the + * last time indication */ + if (trx == bts->c0) { + unsigned int num_rach_per_frame; + /* 27 / 51 taken from TS 05.01 Figure 3 */ + if (bts->c0->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4) + num_rach_per_frame = 27; + else + num_rach_per_frame = 51; + + btsb->load.rach.total += frames_expired * num_rach_per_frame; + } return 0; } -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:37 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:37 +0200 Subject: [PATCH 18/33] Relace bts_model_get_time() by get_time() at common part In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-19-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- include/osmo-bts/bts.h | 2 ++ include/osmo-bts/bts_model.h | 2 -- include/osmo-bts/rsl.h | 2 +- src/common/bts.c | 8 ++++++++ src/common/rsl.c | 3 ++- src/osmo-bts-sysmo/oml.c | 11 +---------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index e489973..db30eb4 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -39,5 +39,7 @@ void load_timer_start(struct gsm_bts *bts); void bts_update_status(enum bts_global_status which, int on); +struct gsm_time *get_time(struct gsm_bts *bts); + #endif /* _BTS_H */ diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h index f9b3f0b..64161d2 100644 --- a/include/osmo-bts/bts_model.h +++ b/include/osmo-bts/bts_model.h @@ -12,8 +12,6 @@ int bts_model_init(struct gsm_bts *bts); -struct gsm_time *bts_model_get_time(struct gsm_bts *bts); - int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, struct tlv_parsed *old_attr, struct tlv_parsed *new_attr, void *obj); diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h index 6e8122f..42ea6ef 100644 --- a/include/osmo-bts/rsl.h +++ b/include/osmo-bts/rsl.h @@ -17,7 +17,7 @@ int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime, uint8_t ra, uint8_t acc_delay); int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len); -int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime); +int rsl_tx_chan_act_ack(struct gsm_lchan *lchan); int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_conn_fail(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan); diff --git a/src/common/bts.c b/src/common/bts.c index 6cbafd1..74b5144 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -601,3 +601,11 @@ int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher) sup = (1 << (rsl_cipher - 2)) & bts->support.ciphers; return sup > 0; } + +struct gsm_time *get_time(struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts->role; + + return &btsb->gsm_time; +} + diff --git a/src/common/rsl.c b/src/common/rsl.c index 11c7c71..b2e5622 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -520,8 +520,9 @@ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan) } /* 8.4.2 sending CHANnel ACTIVation ACKnowledge */ -int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime) +int rsl_tx_chan_act_ack(struct gsm_lchan *lchan) { + struct gsm_time *gtime = get_time(lchan->ts->trx->bts); struct msgb *msg; uint8_t chan_nr = gsm_lchan2chan_nr(lchan); uint8_t ie[2]; diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index b590eff..853cb43 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -960,10 +960,8 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) if (lchan->state != LCHAN_S_ACT_REQ) return 0; - struct gsm_time *time; lchan_set_state(lchan, LCHAN_S_ACTIVE); - time = bts_model_get_time(lchan->ts->trx->bts); - rsl_tx_chan_act_ack(lchan, time); + rsl_tx_chan_act_ack(lchan); /* set the initial ciphering parameters for both directions */ l1if_set_ciphering(fl1h, lchan, 0); @@ -1518,13 +1516,6 @@ static int lchan_deactivate_sacch(struct gsm_lchan *lchan) return 0; } -struct gsm_time *bts_model_get_time(struct gsm_bts *bts) -{ - struct femtol1_hdl *fl1h = trx_femtol1_hdl(bts->c0); - - return &fl1h->gsm_time; -} - /* callback from OML */ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, struct tlv_parsed *old_attr, struct tlv_parsed *new_attr, -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:38 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:38 +0200 Subject: [PATCH 19/33] Move chan act/rel/modify from bts_model to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-20-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part replaces channel activation/deactivation/modification routines by MPH_INFO messages. --- include/osmo-bts/bts_model.h | 6 -- include/osmo-bts/l1sap.h | 2 +- src/common/handover.c | 3 +- src/common/l1sap.c | 145 +++++++++++++++++++++++++++++++++++++++++++ src/common/pcu_sock.c | 8 +-- src/common/rsl.c | 25 ++++---- src/osmo-bts-sysmo/l1_if.c | 41 ++++++++++++ src/osmo-bts-sysmo/l1_if.h | 7 +++ src/osmo-bts-sysmo/oml.c | 60 ++++++++---------- 9 files changed, 240 insertions(+), 57 deletions(-) diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h index 64161d2..a219d5b 100644 --- a/include/osmo-bts/bts_model.h +++ b/include/osmo-bts/bts_model.h @@ -25,12 +25,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state); -int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp); -int bts_model_rsl_chan_rel(struct gsm_lchan *lchan); -int bts_model_rsl_chan_mod(struct gsm_lchan *lchan); -int bts_model_rsl_deact_sacch(struct gsm_lchan *lchan); -int bts_model_rsl_mode_modify(struct gsm_lchan *lchan); - int bts_model_trx_deact_rf(struct gsm_bts_trx *trx); int bts_model_trx_close(struct gsm_bts_trx *trx); diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index a1dc303..dee430f 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -56,7 +56,7 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, unsigned int rtp_pl_len); /* channel control */ -int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr); diff --git a/src/common/handover.c b/src/common/handover.c index 26a3f51..03433ea 100644 --- a/src/common/handover.c +++ b/src/common/handover.c @@ -33,6 +33,7 @@ #include #include #include +#include /* Transmit a handover related PHYS INFO on given lchan */ static int ho_tx_phys_info(struct gsm_lchan *lchan) @@ -114,7 +115,7 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay) /* Stop handover detection, wait for valid frame */ lchan->ho.active = HANDOVER_WAIT_FRAME; - if (bts_model_rsl_chan_mod(lchan) != 0) { + if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) { LOGP(DHO, LOGL_ERROR, "%s failed to modify channel after handover\n", gsm_lchan_name(lchan)); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 9bbbdf3..e9d815c 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -126,6 +126,67 @@ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, return rc; } +/* activation confirm received from bts model */ +static int l1sap_info_act_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_act_cnf_param *info_act_cnf) +{ + struct gsm_lchan *lchan; + + LOGP(DL1P, LOGL_INFO, "activate confirm chan_nr=%02x trx=%d\n", + info_act_cnf->chan_nr, trx->nr); + + lchan = &trx->ts[L1SAP_CHAN2TS(info_act_cnf->chan_nr)] + .lchan[l1sap_chan2ss(info_act_cnf->chan_nr)]; + + if (info_act_cnf->cause) + rsl_tx_chan_act_nack(lchan, info_act_cnf->cause); + else + rsl_tx_chan_act_ack(lchan); + + return 0; +} + +/* activation confirm received from bts model */ +static int l1sap_info_rel_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_act_cnf_param *info_act_cnf) +{ + struct gsm_lchan *lchan; + + LOGP(DL1P, LOGL_INFO, "deactivate confirm chan_nr=%02x trx=%d\n", + info_act_cnf->chan_nr, trx->nr); + + lchan = &trx->ts[L1SAP_CHAN2TS(info_act_cnf->chan_nr)] + .lchan[l1sap_chan2ss(info_act_cnf->chan_nr)]; + + rsl_tx_rf_rel_ack(lchan); + + return 0; +} + +/* any L1 MPH_INFO confirm prim recevied from bts model */ +static int l1sap_mph_info_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct mph_info_param *info) +{ + int rc = 0; + + switch (info->type) { + case PRIM_INFO_ACTIVATE: + rc = l1sap_info_act_cnf(trx, l1sap, &info->u.act_cnf); + break; + case PRIM_INFO_DEACTIVATE: + rc = l1sap_info_rel_cnf(trx, l1sap, &info->u.act_cnf); + break; + default: + LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO cnf type %d\n", + info->type); + break; + } + + return rc; +} + /* PH-RTS-IND prim recevied from bts model */ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind) @@ -322,6 +383,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_INDICATION): rc = l1sap_mph_info_ind(trx, l1sap, &l1sap->u.info); break; + case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_CONFIRM): + rc = l1sap_mph_info_cnf(trx, l1sap, &l1sap->u.info); + break; case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; @@ -376,3 +440,84 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, return l1sap_down(ts->trx, l1sap); } + +static int l1sap_chan_act_dact_modify(struct gsm_bts_trx *trx, uint8_t chan_nr, + enum osmo_mph_info_type type, uint8_t sacch_only) +{ + struct osmo_phsap_prim l1sap; + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_REQUEST, + NULL); + l1sap.u.info.type = type; + l1sap.u.info.u.act_req.chan_nr = chan_nr; + l1sap.u.info.u.act_req.sacch_only = sacch_only; + + return l1sap_down(trx, &l1sap); +} + +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp) +{ + struct gsm_bts_role_bts *btsb = trx->bts->role; + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)] + .lchan[l1sap_chan2ss(chan_nr)]; + struct gsm48_chan_desc *cd; + int rc; + + LOGP(DL1P, LOGL_INFO, "activating channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + if (tp && TLVP_PRESENT(tp, GSM48_IE_CHANDESC_2) && + TLVP_LEN(tp, GSM48_IE_CHANDESC_2) >= sizeof(*cd)) { + cd = (struct gsm48_chan_desc *) + TLVP_VAL(tp, GSM48_IE_CHANDESC_2); + + /* our L1 only supports one global TSC for all channels + * one one TRX, so we need to make sure not to activate + * channels with a different TSC!! */ + if (cd->h0.tsc != (lchan->ts->trx->bts->bsic & 7)) { + LOGP(DRSL, LOGL_ERROR, "lchan TSC %u != BSIC-TSC %u\n", + cd->h0.tsc, lchan->ts->trx->bts->bsic & 7); + return -RSL_ERR_SERV_OPT_UNIMPL; + } + } + + lchan->sacch_deact = 0; + lchan->s = btsb->radio_link_timeout; + + rc = l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); + if (rc) + return -RSL_ERR_EQUIPMENT_FAIL; + return 0; +} + +int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + LOGP(DL1P, LOGL_INFO, "deactivating channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, + 0); +} + +int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)] + .lchan[l1sap_chan2ss(chan_nr)]; + + LOGP(DL1P, LOGL_INFO, "deactivating sacch chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + lchan->sacch_deact = 1; + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, + 1); +} + +int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + LOGP(DL1P, LOGL_INFO, "modifying channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_MODIFY, 0); +} diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 515993e..a4ca25f 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -39,7 +39,6 @@ #include #include #include -#include #include uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); @@ -543,9 +542,9 @@ static int pcu_rx_act_req(struct gsm_bts *bts, return -EINVAL; } if (act_req->activate) - bts_model_rsl_chan_act(lchan, NULL); + l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL); else - bts_model_rsl_chan_rel(lchan); + l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan)); return 0; } @@ -650,7 +649,8 @@ static void pcu_sock_close(struct pcu_sock_state *state) if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED && ts->pchan == GSM_PCHAN_PDCH) { ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU; - bts_model_rsl_chan_rel(ts->lchan); + l1sap_chan_rel(trx, + gsm_lchan2chan_nr(ts->lchan)); } } } diff --git a/src/common/rsl.c b/src/common/rsl.c index b2e5622..1a52c6e 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -46,6 +46,7 @@ #include #include #include +#include //#define FAKE_CIPH_MODE_COMPL @@ -826,7 +827,7 @@ static int rsl_rx_chan_activ(struct msgb *msg) /* actually activate the channel in the BTS */ lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - rc = bts_model_rsl_chan_act(msg->lchan, &tp); + rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr, &tp); if (rc < 0) return rsl_tx_chan_act_nack(lchan, -rc); @@ -834,10 +835,8 @@ static int rsl_rx_chan_activ(struct msgb *msg) } /* 8.4.14 RF CHANnel RELease is received */ -static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan) +static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) { - int rc; - if (lchan->abis_ip.rtp_socket) { rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); @@ -849,9 +848,11 @@ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan) handover_reset(lchan); lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - rc = bts_model_rsl_chan_rel(lchan); + l1sap_chan_rel(lchan->ts->trx, chan_nr); + + lapdm_channel_exit(&lchan->lapdm_ch); - return rc; + return 0; } #ifdef FAKE_CIPH_MODE_COMPL @@ -1034,10 +1035,10 @@ static int rsl_tx_mode_modif_ack(struct gsm_lchan *lchan) /* 8.4.9 MODE MODIFY */ static int rsl_rx_mode_modif(struct msgb *msg) { + struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); struct gsm_lchan *lchan = msg->lchan; struct rsl_ie_chan_mode *cm; struct tlv_parsed tp; - int rc; rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); @@ -1078,12 +1079,12 @@ static int rsl_rx_mode_modif(struct msgb *msg) /* 9.3.53 MultiRate Control */ /* 9.3.54 Supported Codec Types */ - rc = bts_model_rsl_mode_modify(msg->lchan); + l1sap_chan_modify(lchan->ts->trx, dch->chan_nr); /* FIXME: delay this until L1 says OK? */ - rsl_tx_mode_modif_ack(msg->lchan); + rsl_tx_mode_modif_ack(lchan); - return rc; + return 0; } /* 8.4.20 SACCH INFO MODify */ @@ -1734,13 +1735,13 @@ static int rsl_rx_dchan(struct gsm_bts_trx *trx, struct msgb *msg) ret = rsl_rx_chan_activ(msg); break; case RSL_MT_RF_CHAN_REL: - ret = rsl_rx_rf_chan_rel(msg->lchan); + ret = rsl_rx_rf_chan_rel(msg->lchan, dch->chan_nr); break; case RSL_MT_SACCH_INFO_MODIFY: ret = rsl_rx_sacch_inf_mod(msg); break; case RSL_MT_DEACTIVATE_SACCH: - ret = bts_model_rsl_deact_sacch(msg->lchan); + ret = l1sap_chan_deact_sacch(trx, dch->chan_nr); break; case RSL_MT_ENCR_CMD: ret = rsl_rx_encr_cmd(msg); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 59a30f2..4a398ea 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -532,6 +532,44 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, return 0; } +static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, + struct osmo_phsap_prim *l1sap) +{ + uint8_t u8Tn, ss; + uint8_t chan_nr; + struct gsm_lchan *lchan; + int rc = 0; + + switch (l1sap->u.info.type) { + case PRIM_INFO_ACTIVATE: + case PRIM_INFO_DEACTIVATE: + case PRIM_INFO_MODIFY: + chan_nr = l1sap->u.info.u.act_req.chan_nr; + u8Tn = L1SAP_CHAN2TS(chan_nr); + ss = l1sap_chan2ss(chan_nr); + lchan = &trx->ts[u8Tn].lchan[ss]; + if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) + l1if_rsl_chan_act(lchan); + else if (l1sap->u.info.type == PRIM_INFO_MODIFY) { + if (lchan->ho.active == HANDOVER_WAIT_FRAME) + l1if_rsl_chan_mod(lchan); + else + l1if_rsl_mode_modify(lchan); + } else if (l1sap->u.info.u.act_req.sacch_only) + l1if_rsl_deact_sacch(lchan); + else + l1if_rsl_chan_rel(lchan); + msgb_free(msg); + break; + default: + LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", + l1sap->u.info.type); + rc = -EINVAL; + } + + return rc; +} + /* primitive from common part */ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) { @@ -542,6 +580,9 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): rc = ph_data_req(trx, msg, l1sap); break; + case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST): + rc = mph_info_req(trx, msg, l1sap); + break; default: LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n", l1sap->oph.primitive, l1sap->oph.operation); diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 5efa25b..b0a624d 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -119,6 +119,13 @@ int l1if_set_ciphering(struct femtol1_hdl *fl1h, struct gsm_lchan *lchan, int dir_downlink); +/* channel control */ +int l1if_rsl_chan_act(struct gsm_lchan *lchan); +int l1if_rsl_chan_rel(struct gsm_lchan *lchan); +int l1if_rsl_chan_mod(struct gsm_lchan *lchan); +int l1if_rsl_deact_sacch(struct gsm_lchan *lchan); +int l1if_rsl_mode_modify(struct gsm_lchan *lchan); + /* calibration loading */ int calib_load(struct femtol1_hdl *fl1h); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 853cb43..f490195 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -37,11 +37,27 @@ #include #include #include +#include #include "l1_if.h" #include "femtobts.h" #include "utils.h" +static int mph_info_chan_confirm(struct gsm_lchan *lchan, + enum osmo_mph_info_type type, uint8_t cause) +{ + struct osmo_phsap_prim l1sap; + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_CONFIRM, + NULL); + l1sap.u.info.type = type; + l1sap.u.info.u.act_cnf.chan_nr = gsm_lchan2chan_nr(lchan); + l1sap.u.info.u.act_cnf.cause = cause; + + return l1sap_up(lchan->ts->trx, &l1sap); +} + enum sapi_cmd_type { SAPI_CMD_ACTIVATE, SAPI_CMD_CONFIG_CIPHERING, @@ -950,7 +966,7 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) gsm_lchan_name(lchan), status); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); - rsl_tx_chan_act_nack(lchan, RSL_ERR_PROCESSOR_OVERLOAD); + mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, RSL_ERR_PROCESSOR_OVERLOAD); return -1; } @@ -961,7 +977,7 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) return 0; lchan_set_state(lchan, LCHAN_S_ACTIVE); - rsl_tx_chan_act_ack(lchan); + mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, 0); /* set the initial ciphering parameters for both directions */ l1if_set_ciphering(fl1h, lchan, 0); @@ -983,7 +999,6 @@ static void enqueue_sapi_act_cmd(struct gsm_lchan *lchan, int sapi, int dir) int lchan_activate(struct gsm_lchan *lchan) { - struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role; struct femtol1_hdl *fl1h = trx_femtol1_hdl(lchan->ts->trx); const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; unsigned int i; @@ -1017,8 +1032,6 @@ int lchan_activate(struct gsm_lchan *lchan) #warning "FIXME: Should this be in sapi_activate_cb?" lchan_init_lapdm(lchan); - lchan->s = btsb->radio_link_timeout; - return 0; } @@ -1279,7 +1292,7 @@ int l1if_set_ciphering(struct femtol1_hdl *fl1h, return 0; } -int bts_model_rsl_mode_modify(struct gsm_lchan *lchan) +int l1if_rsl_mode_modify(struct gsm_lchan *lchan) { if (lchan->state != LCHAN_S_ACTIVE) return -1; @@ -1389,7 +1402,7 @@ static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status) gsm_lchan_name(lchan)); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); - rsl_tx_rf_rel_ack(lchan); + mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); return -1; } @@ -1401,7 +1414,7 @@ static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status) return 0; lchan_set_state(lchan, LCHAN_S_NONE); - rsl_tx_rf_rel_ack(lchan); + mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); return 0; } @@ -1476,7 +1489,7 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n", gsm_lchan_name(lchan)); lchan_set_state(lchan, LCHAN_S_BROKEN); - rsl_tx_rf_rel_ack(lchan); + mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); } return res; @@ -1633,30 +1646,11 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); } -int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) + +int l1if_rsl_chan_act(struct gsm_lchan *lchan) { //uint8_t mode = *TLVP_VAL(tp, RSL_IE_CHAN_MODE); //uint8_t type = *TLVP_VAL(tp, RSL_IE_ACT_TYPE); - struct gsm48_chan_desc *cd; - - /* osmo-pcu calls this without a valid 'tp' parameter, so we - * need to make sure we don't crash here */ - if (tp && TLVP_PRESENT(tp, GSM48_IE_CHANDESC_2) && - TLVP_LEN(tp, GSM48_IE_CHANDESC_2) >= sizeof(*cd)) { - cd = (struct gsm48_chan_desc *) - TLVP_VAL(tp, GSM48_IE_CHANDESC_2); - - /* our L1 only supports one global TSC for all channels - * one one TRX, so we need to make sure not to activate - * channels with a different TSC!! */ - if (cd->h0.tsc != (lchan->ts->trx->bts->bsic & 7)) { - LOGP(DRSL, LOGL_ERROR, "lchan TSC %u != BSIC-TSC %u\n", - cd->h0.tsc, lchan->ts->trx->bts->bsic & 7); - return -RSL_ERR_SERV_OPT_UNIMPL; - } - } - - lchan->sacch_deact = 0; lchan_activate(lchan); return 0; } @@ -1665,7 +1659,7 @@ int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) * Modify the given lchan in the handover scenario. This is a lot like * second channel activation but with some additional activation. */ -int bts_model_rsl_chan_mod(struct gsm_lchan *lchan) +int l1if_rsl_chan_mod(struct gsm_lchan *lchan) { const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; unsigned int i; @@ -1689,7 +1683,7 @@ int bts_model_rsl_chan_mod(struct gsm_lchan *lchan) return 0; } -int bts_model_rsl_chan_rel(struct gsm_lchan *lchan) +int l1if_rsl_chan_rel(struct gsm_lchan *lchan) { /* A duplicate RF Release Request, ignore it */ if (lchan->state == LCHAN_S_REL_REQ) { @@ -1702,7 +1696,7 @@ int bts_model_rsl_chan_rel(struct gsm_lchan *lchan) return 0; } -int bts_model_rsl_deact_sacch(struct gsm_lchan *lchan) +int l1if_rsl_deact_sacch(struct gsm_lchan *lchan) { /* Only de-activate the SACCH if the lchan is active */ if (lchan->state != LCHAN_S_ACTIVE) -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:39 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:39 +0200 Subject: [PATCH 20/33] l1sap: re-introduce a comment that was lost during l1sap merge In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-21-git-send-email-laforge@gnumonks.org> --- src/common/l1sap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index e9d815c..c631860 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -467,6 +467,8 @@ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed * LOGP(DL1P, LOGL_INFO, "activating channel chan_nr=%02x trx=%d\n", chan_nr, trx->nr); + /* osmo-pcu calls this without a valid 'tp' parameter, so we + * need to make sure ew don't crash here */ if (tp && TLVP_PRESENT(tp, GSM48_IE_CHANDESC_2) && TLVP_LEN(tp, GSM48_IE_CHANDESC_2) >= sizeof(*cd)) { cd = (struct gsm48_chan_desc *) -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:40 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:40 +0200 Subject: [PATCH 21/33] Add TCH messages to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-22-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves TCH handling from osmo-bts-sysmo to common part. The RTP handling is done at the common part, so they can be used by other BTS models. --- include/osmo-bts/bts_model.h | 3 - src/common/l1sap.c | 151 ++++++++++++++++++++++++++++++++++++++ src/common/rsl.c | 3 +- src/osmo-bts-sysmo/l1_if.c | 169 ++++++++++++++++++++++++++++--------------- src/osmo-bts-sysmo/l1_if.h | 4 +- src/osmo-bts-sysmo/tch.c | 120 ++++++++---------------------- 6 files changed, 294 insertions(+), 156 deletions(-) diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h index a219d5b..a0f4542 100644 --- a/include/osmo-bts/bts_model.h +++ b/include/osmo-bts/bts_model.h @@ -28,9 +28,6 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, int bts_model_trx_deact_rf(struct gsm_bts_trx *trx); int bts_model_trx_close(struct gsm_bts_trx *trx); -void bts_model_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len); - int bts_model_vty_init(struct gsm_bts *bts); void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index c631860..9068bb8 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -286,6 +286,72 @@ static int l1sap_handover_rach(struct gsm_bts_trx *trx, return 0; } +/* TCH-RTS-IND prim recevied from bts model */ +static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct ph_tch_param *rts_ind) +{ + struct msgb *resp_msg; + struct osmo_phsap_prim *resp_l1sap, empty_l1sap; + struct gsm_time g_time; + struct gsm_lchan *lchan; + uint8_t chan_nr; + uint8_t tn, ss; + uint32_t fn; + + chan_nr = rts_ind->chan_nr; + fn = rts_ind->fn; + tn = L1SAP_CHAN2TS(chan_nr); + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1P, "Rx TCH-RTS.ind %02u/%02u/%02u chan_nr=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr); + + /* get timeslot and subslot */ + tn = L1SAP_CHAN2TS(chan_nr); + if (L1SAP_IS_CHAN_TCHH(chan_nr)) + ss = L1SAP_CHAN2SS_TCHH(chan_nr); /* TCH/H */ + else + ss = 0; /* TCH/F */ + lchan = &trx->ts[tn].lchan[ss]; + + if (!lchan->loopback && lchan->abis_ip.rtp_socket) { + osmo_rtp_socket_poll(lchan->abis_ip.rtp_socket); + /* FIXME: we _assume_ that we never miss TDMA + * frames and that we always get to this point + * for every to-be-transmitted voice frame. A + * better solution would be to compute + * rx_user_ts based on how many TDMA frames have + * elapsed since the last call */ + lchan->abis_ip.rtp_socket->rx_user_ts += GSM_RTP_DURATION; + } + /* get a msgb from the dl_tx_queue */ + resp_msg = msgb_dequeue(&lchan->dl_tch_queue); + if (!resp_msg) { + LOGP(DL1P, LOGL_DEBUG, "%s DL TCH Tx queue underrun\n", + gsm_lchan_name(lchan)); + resp_l1sap = &empty_l1sap; + } else { + resp_msg->l2h = resp_msg->data; + msgb_push(resp_msg, sizeof(*resp_l1sap)); + resp_msg->l1h = resp_msg->data; + resp_l1sap = msgb_l1sap_prim(resp_msg); + } + + memset(resp_l1sap, 0, sizeof(*resp_l1sap)); + osmo_prim_init(&resp_l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_REQUEST, + resp_msg); + resp_l1sap->u.tch.chan_nr = chan_nr; + resp_l1sap->u.tch.fn = fn; + + DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr); + + l1sap_down(trx, resp_l1sap); + + return 0; +} + /* DATA received from bts model */ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) @@ -334,6 +400,57 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, return 0; } +/* TCH received from bts model */ +static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, + struct ph_tch_param *tch_ind) +{ + struct msgb *msg = l1sap->oph.msg; + struct gsm_time g_time; + struct gsm_lchan *lchan; + uint8_t tn, ss, chan_nr; + uint32_t fn; + + chan_nr = tch_ind->chan_nr; + fn = tch_ind->fn; + tn = L1SAP_CHAN2TS(chan_nr); + if (L1SAP_IS_CHAN_TCHH(chan_nr)) + ss = L1SAP_CHAN2SS_TCHH(chan_nr); + else + ss = 0; + lchan = &trx->ts[tn].lchan[ss]; + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1P, "Rx TCH.ind %02u/%02u/%02u chan_nr=%d\n", + g_time.t1, g_time.t2, g_time.t3, chan_nr); + + msgb_pull(msg, sizeof(*l1sap)); + + /* hand msg to RTP code for transmission */ + if (lchan->abis_ip.rtp_socket) + osmo_rtp_send_frame(lchan->abis_ip.rtp_socket, + msg->data, msg->len, 160); + + /* if loopback is enabled, also queue received RTP data */ + if (lchan->loopback) { + struct msgb *tmp; + int count = 0; + + /* make sure the queue doesn't get too long */ + llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) + count++; + while (count >= 1) { + tmp = msgb_dequeue(&lchan->dl_tch_queue); + msgb_free(tmp); + count--; + } + + msgb_enqueue(&lchan->dl_tch_queue, msg); + } + + return 0; +} + /* RACH received from bts model */ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind) @@ -389,9 +506,15 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; + case OSMO_PRIM(PRIM_TCH_RTS, PRIM_OP_INDICATION): + rc = l1sap_tch_rts_ind(trx, l1sap, &l1sap->u.tch); + break; case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_INDICATION): rc = l1sap_ph_data_ind(trx, l1sap, &l1sap->u.data); break; + case OSMO_PRIM(PRIM_TCH, PRIM_OP_INDICATION): + rc = l1sap_tch_ind(trx, l1sap, &l1sap->u.tch); + break; case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION): rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind); break; @@ -441,6 +564,34 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, return l1sap_down(ts->trx, l1sap); } +/*! \brief call-back function for incoming RTP */ +void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, + unsigned int rtp_pl_len) +{ + struct gsm_lchan *lchan = rs->priv; + struct msgb *msg, *tmp; + struct osmo_phsap_prim *l1sap; + int count = 0; + + msg = l1sap_msgb_alloc(rtp_pl_len); + if (!msg) + return; + memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); + msgb_pull(msg, sizeof(*l1sap)); + + + /* make sure the queue doesn't get too long */ + llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) + count++; + while (count >= 2) { + tmp = msgb_dequeue(&lchan->dl_tch_queue); + msgb_free(tmp); + count--; + } + + msgb_enqueue(&lchan->dl_tch_queue, msg); +} + static int l1sap_chan_act_dact_modify(struct gsm_bts_trx *trx, uint8_t chan_nr, enum osmo_mph_info_type type, uint8_t sacch_only) { diff --git a/src/common/rsl.c b/src/common/rsl.c index 1a52c6e..dc49177 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -1395,7 +1394,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) OSMO_RTP_P_JITBUF, btsb->rtp_jitter_buf_ms); lchan->abis_ip.rtp_socket->priv = lchan; - lchan->abis_ip.rtp_socket->rx_cb = &bts_model_rtp_rx_cb; + lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb; if (connect_ip && connect_port) { /* if CRCX specifies a remote IP, we can bind() diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 4a398ea..5f7b8cf 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -38,8 +38,6 @@ #include #include -#include - #include #include #include @@ -532,6 +530,93 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, return 0; } +static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, + struct osmo_phsap_prim *l1sap) +{ + struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx); + struct gsm_lchan *lchan; + uint32_t u32Fn; + uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi, ss; + uint8_t chan_nr; + GsmL1_Prim_t *l1p; + struct msgb *nmsg; + + chan_nr = l1sap->u.tch.chan_nr; + u32Fn = l1sap->u.tch.fn; + u8Tn = L1SAP_CHAN2TS(chan_nr); + u8BlockNbr = (u32Fn % 13) >> 2; + if (L1SAP_IS_CHAN_TCHH(chan_nr)) { + ss = subCh = L1SAP_CHAN2SS_TCHH(chan_nr); + sapi = GsmL1_Sapi_TchH; + } else { + subCh = 0x1f; + ss = 0; + sapi = GsmL1_Sapi_TchF; + } + + lchan = &trx->ts[u8Tn].lchan[ss]; + + /* create new message and fill data */ + if (msg) { + msgb_pull(msg, sizeof(*l1sap)); + /* create new message */ + nmsg = l1p_msgb_alloc(); + if (!nmsg) + return -ENOMEM; + l1p = msgb_l1prim(nmsg); + l1if_tch_encode(lchan, + l1p->u.phDataReq.msgUnitParam.u8Buffer, + &l1p->u.phDataReq.msgUnitParam.u8Size, + msg->data, msg->len); + } + + /* no message/data, we generate an empty traffic msg */ + if (!nmsg) + nmsg = gen_empty_tch_msg(lchan); + + /* no traffic message, we generate an empty msg */ + if (!nmsg) { + nmsg = l1p_msgb_alloc(); + if (!nmsg) + return -ENOMEM; + } + + l1p = msgb_l1prim(nmsg); + + /* if we provide data, or if data is already in nmsg */ + if (l1p->u.phDataReq.msgUnitParam.u8Size) { + /* data request */ + GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq; + + l1p->id = GsmL1_PrimId_PhDataReq; + + data_req->hLayer1 = fl1->hLayer1; + data_req->u8Tn = u8Tn; + data_req->u32Fn = u32Fn; + data_req->sapi = sapi; + data_req->subCh = subCh; + data_req->u8BlockNbr = u8BlockNbr; + } else { + /* empty frame */ + GsmL1_PhEmptyFrameReq_t *empty_req = + &l1p->u.phEmptyFrameReq; + + l1p->id = GsmL1_PrimId_PhEmptyFrameReq; + + empty_req->hLayer1 = fl1->hLayer1; + empty_req->u8Tn = u8Tn; + empty_req->u32Fn = u32Fn; + empty_req->sapi = sapi; + empty_req->subCh = subCh; + empty_req->u8BlockNbr = u8BlockNbr; + } + /* send message to DSP's queue */ + osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + + msgb_free(msg); + return 0; +} + static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, struct osmo_phsap_prim *l1sap) { @@ -580,6 +665,9 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): rc = ph_data_req(trx, msg, l1sap); break; + case OSMO_PRIM(PRIM_TCH, PRIM_OP_REQUEST): + rc = ph_tch_req(trx, msg, l1sap); + break; case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST): rc = mph_info_req(trx, msg, l1sap); break; @@ -646,6 +734,12 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, return 0; } break; + case GsmL1_Sapi_TchF: + cbits = 0x01; + break; + case GsmL1_Sapi_TchH: + cbits = 0x02 + subCh; + break; case GsmL1_Sapi_Ptcch: if (!L1SAP_IS_PTCCH(u32Fn)) { LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame " @@ -690,7 +784,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, uint8_t chan_nr, link_id; uint32_t fn; - /* check if primitive should be handled by common part */ chan_nr = chan_nr_by_sapi(trx->ts[rts_ind->u8Tn].pchan, rts_ind->sapi, rts_ind->subCh, rts_ind->u8Tn, rts_ind->u32Fn); @@ -701,11 +794,19 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive\n"); l1sap = msgb_l1sap_prim(l1p_msg); - osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RTS, - PRIM_OP_INDICATION, l1p_msg); - l1sap->u.data.link_id = link_id; - l1sap->u.data.chan_nr = chan_nr; - l1sap->u.data.fn = fn; + if (rts_ind->sapi == GsmL1_Sapi_TchF + || rts_ind->sapi == GsmL1_Sapi_TchH) { + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH_RTS, + PRIM_OP_INDICATION, l1p_msg); + l1sap->u.tch.chan_nr = chan_nr; + l1sap->u.tch.fn = fn; + } else { + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RTS, + PRIM_OP_INDICATION, l1p_msg); + l1sap->u.data.link_id = link_id; + l1sap->u.data.chan_nr = chan_nr; + l1sap->u.data.fn = fn; + } return l1sap_up(trx, l1sap); } @@ -716,50 +817,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, g_time.t1, g_time.t2, g_time.t3, get_value_string(femtobts_l1sapi_names, rts_ind->sapi)); - /* In case of TCH downlink trasnmission, we already have a l1 - * primitive msgb pre-allocated and pre-formatted in the - * dl_tch_queue. All we need to do is to pull it off the queue - * and transmit it */ - switch (rts_ind->sapi) { - case GsmL1_Sapi_TchF: - case GsmL1_Sapi_TchH: - /* resolve the L2 entity using rts_ind->hLayer2 */ - lchan = l1if_hLayer_to_lchan(trx, rts_ind->hLayer2); - if (!lchan) - break; - - if (!lchan->loopback && lchan->abis_ip.rtp_socket) { - osmo_rtp_socket_poll(lchan->abis_ip.rtp_socket); - /* FIXME: we _assume_ that we never miss TDMA - * frames and that we always get to this point - * for every to-be-transmitted voice frame. A - * better solution would be to compute - * rx_user_ts based on how many TDMA frames have - * elapsed since the last call */ - lchan->abis_ip.rtp_socket->rx_user_ts += GSM_RTP_DURATION; - } - /* get a msgb from the dl_tx_queue */ - resp_msg = msgb_dequeue(&lchan->dl_tch_queue); - /* if there is none, try to generate empty TCH frame - * like AMR SID_BAD */ - if (!resp_msg) { - LOGP(DL1C, LOGL_DEBUG, "%s DL TCH Tx queue underrun\n", - gsm_lchan_name(lchan)); - resp_msg = gen_empty_tch_msg(lchan); - /* if there really is none, break here and send empty */ - if (!resp_msg) - break; - } - - /* fill header */ - data_req_from_rts_ind(msgb_l1prim(resp_msg), rts_ind); - /* actually transmit it */ - goto tx; - break; - default: - break; - } - /* in all other cases, we need to allocate a new PH-DATA.ind * primitive msgb and start to fill it */ resp_msg = l1p_msgb_alloc(); @@ -820,12 +877,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, msgb_free(pp.oph.msg); } break; - case GsmL1_Sapi_TchF: - case GsmL1_Sapi_TchH: - /* only hit in case we have a RTP underflow, as real TCH - * frames are handled way above */ - goto empty_frame; - break; case GsmL1_Sapi_FacchF: case GsmL1_Sapi_FacchH: /* resolve the L2 entity using rts_ind->hLayer2 */ @@ -1044,7 +1095,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i case GsmL1_Sapi_TchF: case GsmL1_Sapi_TchH: /* TCH speech frame handling */ - rc = l1if_tch_rx(lchan, l1p_msg); + rc = l1if_tch_rx(trx, chan_nr, l1p_msg); break; case GsmL1_Sapi_Pdtch: case GsmL1_Sapi_Pacch: diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index b0a624d..6f58e95 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -110,7 +110,9 @@ uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan); struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer); /* tch.c */ -int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg); +void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, + const uint8_t *rtp_pl, unsigned int rtp_pl_len); +int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index d101b47..997b45b 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -422,7 +423,7 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, #define RTP_MSGB_ALLOC_SIZE 512 -/*! \brief call-back function for incoming RTP +/*! \brief function for incoming RTP via TCH.req * \param rs RTP Socket * \param[in] rtp_pl buffer containing RTP payload * \param[in] rtp_pl_len length of \a rtp_pl @@ -434,34 +435,18 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, * yet, as things like the frame number, etc. are unknown at the time we * pre-fill the primtive. */ -void bts_model_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, - unsigned int rtp_pl_len) +void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, + const uint8_t *rtp_pl, unsigned int rtp_pl_len) { - struct gsm_lchan *lchan = rs->priv; - struct msgb *msg; - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; uint8_t *payload_type; uint8_t *l1_payload; int rc; - /* skip processing of incoming RTP frames if we are in loopback mode */ - if (lchan->loopback) - return; - - msg = l1p_msgb_alloc(); - if (!msg) { - LOGP(DRTP, LOGL_ERROR, "%s: Failed to allocate Rx payload.\n", - gsm_lchan_name(lchan)); - return; - } + DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), + osmo_hexdump(rtp_pl, rtp_pl_len)); - l1p = msgb_l1prim(msg); - data_req = &l1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - payload_type = &msu_param->u8Buffer[0]; - l1_payload = &msu_param->u8Buffer[1]; + payload_type = &data[0]; + l1_payload = &data[1]; switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_V1: @@ -496,38 +481,17 @@ void bts_model_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, if (rc < 0) { LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", gsm_lchan_name(lchan)); - msgb_free(msg); return; } - msu_param->u8Size = rc + 1; - + *len = rc + 1; - /* make sure the number of entries in the dl_tch_queue is never - * more than 3 */ - { - struct msgb *tmp; - int count = 0; - - llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) - count++; - - DEBUGP(DL1C, "%s DL TCH queue length = %u\n", - gsm_lchan_name(lchan), count); - - while (count >= 2) { - tmp = msgb_dequeue(&lchan->dl_tch_queue); - msgb_free(tmp); - count--; - } - } - - /* enqueue msgb to be transmitted to L1 */ - msgb_enqueue(&lchan->dl_tch_queue, msg); + DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), + osmo_hexdump(data, *len)); } /*! \brief receive a traffic L1 primitive for a given lchan */ -int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg) +int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) { GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg); GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; @@ -535,50 +499,15 @@ int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg) uint8_t *payload = data_ind->msgUnitParam.u8Buffer + 1; uint8_t payload_len; struct msgb *rmsg = NULL; + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; if (data_ind->msgUnitParam.u8Size < 1) { - LOGP(DL1C, LOGL_ERROR, "%s Rx Payload size 0\n", - gsm_lchan_name(lchan)); + LOGP(DL1C, LOGL_ERROR, "chan_nr %d Rx Payload size 0\n", + chan_nr); return -EINVAL; } payload_len = data_ind->msgUnitParam.u8Size - 1; - if (lchan->loopback) { - GsmL1_Prim_t *rl1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - - struct msgb *tmp; - int count = 0; - - /* generate a new msgb from the paylaod */ - rmsg = l1p_msgb_alloc(); - if (!rmsg) - return -ENOMEM; - - rl1p = msgb_l1prim(rmsg); - data_req = &rl1p->u.phDataReq; - msu_param = &data_req->msgUnitParam; - - memcpy(msu_param->u8Buffer, - data_ind->msgUnitParam.u8Buffer, - data_ind->msgUnitParam.u8Size); - msu_param->u8Size = data_ind->msgUnitParam.u8Size; - - /* make sure the queue doesn't get too long */ - llist_for_each_entry(tmp, &lchan->dl_tch_queue, list) - count++; - while (count >= 1) { - tmp = msgb_dequeue(&lchan->dl_tch_queue); - msgb_free(tmp); - count--; - } - - msgb_enqueue(&lchan->dl_tch_queue, rmsg); - - return 0; - } - switch (payload_type) { case GsmL1_TchPlType_Fr: #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) @@ -622,11 +551,20 @@ int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg) } if (rmsg) { - /* hand rmsg to RTP code for transmission */ - if (lchan->abis_ip.rtp_socket) - osmo_rtp_send_frame(lchan->abis_ip.rtp_socket, - rmsg->data, rmsg->len, 160); - msgb_free(rmsg); + struct osmo_phsap_prim *l1sap; + + LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", + gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, rmsg->len)); + + /* add l1sap header */ + rmsg->l2h = rmsg->data; + msgb_push(rmsg, sizeof(*l1sap)); + rmsg->l1h = rmsg->data; + l1sap = msgb_l1sap_prim(rmsg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, rmsg); + l1sap->u.tch.chan_nr = chan_nr; + + return l1sap_up(trx, l1sap); } return 0; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:41 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:41 +0200 Subject: [PATCH 22/33] l1sap: Use {data, empty}_req_from_l1sap() and avoid code duplication In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-23-git-send-email-laforge@gnumonks.org> --- src/osmo-bts-sysmo/l1_if.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 5f7b8cf..3b5e823 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -586,29 +586,12 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, /* if we provide data, or if data is already in nmsg */ if (l1p->u.phDataReq.msgUnitParam.u8Size) { /* data request */ - GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq; - - l1p->id = GsmL1_PrimId_PhDataReq; - - data_req->hLayer1 = fl1->hLayer1; - data_req->u8Tn = u8Tn; - data_req->u32Fn = u32Fn; - data_req->sapi = sapi; - data_req->subCh = subCh; - data_req->u8BlockNbr = u8BlockNbr; + data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, + u8BlockNbr, + l1p->u.phDataReq.msgUnitParam.u8Size); } else { /* empty frame */ - GsmL1_PhEmptyFrameReq_t *empty_req = - &l1p->u.phEmptyFrameReq; - - l1p->id = GsmL1_PrimId_PhEmptyFrameReq; - - empty_req->hLayer1 = fl1->hLayer1; - empty_req->u8Tn = u8Tn; - empty_req->u32Fn = u32Fn; - empty_req->sapi = sapi; - empty_req->subCh = subCh; - empty_req->u8BlockNbr = u8BlockNbr; + empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } /* send message to DSP's queue */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:42 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:42 +0200 Subject: [PATCH 23/33] l1sap: Avoid compiler warnings regarding uninitialized nmsg In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-24-git-send-email-laforge@gnumonks.org> --- src/osmo-bts-sysmo/l1_if.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3b5e823..f17972b 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -449,7 +449,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, { struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx); uint32_t u32Fn; - uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi; + uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi = 0; uint8_t chan_nr, link_id; GsmL1_Prim_t *l1p; int len; @@ -539,7 +539,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi, ss; uint8_t chan_nr; GsmL1_Prim_t *l1p; - struct msgb *nmsg; + struct msgb *nmsg = NULL; chan_nr = l1sap->u.tch.chan_nr; u32Fn = l1sap->u.tch.fn; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:43 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:43 +0200 Subject: [PATCH 24/33] Add SDCCH/SACCH/FACCH messages to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-25-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves control channel message primitives from osmo-bts-sysmo to common part. In order to control ciphering fo BTS model, CIPHER (MPH_INFO) messages are used. --- src/common/l1sap.c | 181 ++++++++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/l1_if.c | 219 ++++++++++++++++++--------------------------- 2 files changed, 265 insertions(+), 135 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 9068bb8..14dbde9 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -69,6 +69,54 @@ struct msgb *l1sap_msgb_alloc(unsigned int l2_len) return msg; } +static int l1sap_tx_ciph_req(struct gsm_bts_trx *trx, uint8_t chan_nr, + uint8_t downlink, uint8_t uplink) +{ + struct osmo_phsap_prim l1sap_ciph; + + osmo_prim_init(&l1sap_ciph.oph, SAP_GSM_PH, PRIM_MPH_INFO, + PRIM_OP_REQUEST, NULL); + l1sap_ciph.u.info.type = PRIM_INFO_ACT_CIPH; + l1sap_ciph.u.info.u.ciph_req.chan_nr = chan_nr; + l1sap_ciph.u.info.u.ciph_req.downlink = downlink; + l1sap_ciph.u.info.u.ciph_req.uplink = uplink; + + return l1sap_down(trx, &l1sap_ciph); +} + + +/* check if the message is a GSM48_MT_RR_CIPH_M_CMD, and if yes, enable + * uni-directional de-cryption on the uplink. We need this ugly layering + * violation as we have no way of passing down L3 metadata (RSL CIPHERING CMD) + * to this point in L1 */ +static int check_for_ciph_cmd(struct msgb *msg, struct gsm_lchan *lchan, + uint8_t chan_nr) +{ + + /* only do this if we are in the right state */ + switch (lchan->ciph_state) { + case LCHAN_CIPH_NONE: + case LCHAN_CIPH_RX_REQ: + break; + default: + return 0; + } + + /* First byte (Address Field) of LAPDm header) */ + if (msg->data[0] != 0x03) + return 0; + /* First byte (protocol discriminator) of RR */ + if ((msg->data[3] & 0xF) != GSM48_PDISC_RR) + return 0; + /* 2nd byte (msg type) of RR */ + if ((msg->data[4] & 0x3F) != GSM48_MT_RR_CIPH_M_CMD) + return 0; + + l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 0, 1); + + return 1; +} + /* time information received from bts model */ static int l1sap_info_time_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, @@ -193,10 +241,13 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, { struct msgb *msg = l1sap->oph.msg; struct gsm_time g_time; + struct gsm_lchan *lchan; uint8_t chan_nr, link_id; - uint8_t tn; + uint8_t tn, ss; uint32_t fn; uint8_t *p, *si; + struct lapdm_entity *le; + struct osmo_phsap_prim pp; int rc; chan_nr = rts_ind->chan_nr; @@ -241,6 +292,52 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, memcpy(p, si, GSM_MACBLOCK_LEN); else memcpy(p, fill_frame, GSM_MACBLOCK_LEN); + } else if (!(chan_nr & 0x80)) { /* only TCH/F, TCH/H, SDCCH/4 and SDCCH/8 have C5 bit cleared */ + if (L1SAP_IS_CHAN_TCHH(chan_nr)) + ss = L1SAP_CHAN2SS_TCHH(chan_nr); /* TCH/H */ + else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) + ss = L1SAP_CHAN2SS_SDCCH4(chan_nr); /* SDCCH/4 */ + else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) + ss = L1SAP_CHAN2SS_SDCCH8(chan_nr); /* SDCCH/8 */ + else + ss = 0; /* TCH/F */ + lchan = &trx->ts[tn].lchan[ss]; + if (L1SAP_IS_LINK_SACCH(link_id)) { + p = msgb_put(msg, GSM_MACBLOCK_LEN); + /* L1-header, if not set/modified by layer 1 */ + p[0] = lchan->ms_power; + p[1] = lchan->rqd_ta; + le = &lchan->lapdm_ch.lapdm_acch; + } else + le = &lchan->lapdm_ch.lapdm_dcch; + rc = lapdm_phsap_dequeue_prim(le, &pp); + if (rc < 0) { + if (L1SAP_IS_LINK_SACCH(link_id)) { + /* No SACCH data from LAPDM pending, send SACCH filling */ + uint8_t *si = lchan_sacch_get(lchan); + if (si) { + /* The +2 is empty space where the DSP inserts the L1 hdr */ + memcpy(p + 2, si, GSM_MACBLOCK_LEN - 2); + } else + memcpy(p + 2, fill_frame, GSM_MACBLOCK_LEN - 2); + } else if ((!L1SAP_IS_CHAN_TCHF(chan_nr) && !L1SAP_IS_CHAN_TCHH(chan_nr)) + || lchan->rsl_cmode == RSL_CMOD_SPD_SIGN) { + /* send fill frame only, if not TCH/x != Signalling, otherwise send empty frame */ + p = msgb_put(msg, GSM_MACBLOCK_LEN); + memcpy(p, fill_frame, GSM_MACBLOCK_LEN); + } /* else the message remains empty, so TCH frames are sent */ + } else { + /* The +2 is empty space where the DSP inserts the L1 hdr */ + if (L1SAP_IS_LINK_SACCH(link_id)) + memcpy(p + 2, pp.oph.msg->data + 2, GSM_MACBLOCK_LEN - 2); + else { + p = msgb_put(msg, GSM_MACBLOCK_LEN); + memcpy(p, pp.oph.msg->data, GSM_MACBLOCK_LEN); + /* check if it is a RR CIPH MODE CMD. if yes, enable RX ciphering */ + check_for_ciph_cmd(pp.oph.msg, lchan, chan_nr); + } + msgb_free(pp.oph.msg); + } } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { p = msgb_put(msg, GSM_MACBLOCK_LEN); #warning "TODO: Yet another assumption that BS_AG_BLKS_RES=1" @@ -352,12 +449,46 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, return 0; } +/* process radio link timeout counter S */ +static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame) +{ + struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role; + + /* if link loss criterion already reached */ + if (lchan->s == 0) { + DEBUGP(DMEAS, "%s radio link counter S already 0.\n", + gsm_lchan_name(lchan)); + return; + } + + if (bad_frame) { + /* count down radio link counter S */ + lchan->s--; + DEBUGP(DMEAS, "%s counting down radio link counter S=%d\n", + gsm_lchan_name(lchan), lchan->s); + if (lchan->s == 0) + rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL); + return; + } + + if (lchan->s < btsb->radio_link_timeout) { + /* count up radio link counter S */ + lchan->s += 2; + if (lchan->s > btsb->radio_link_timeout) + lchan->s = btsb->radio_link_timeout; + DEBUGP(DMEAS, "%s counting up radio link counter S=%d\n", + gsm_lchan_name(lchan), lchan->s); + } +} + /* DATA received from bts model */ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) { struct msgb *msg = l1sap->oph.msg; struct gsm_time g_time; + struct gsm_lchan *lchan; + struct lapdm_entity *le; uint8_t *data = msg->l2h; int len = msgb_l2len(msg); uint8_t chan_nr, link_id; @@ -397,7 +528,53 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, return 0; } - return 0; + lchan = &trx->ts[tn].lchan[ss]; + + /* bad frame */ + if (len == 0) { + if (L1SAP_IS_LINK_SACCH(link_id)) + radio_link_timeout(lchan, 1); + return -EINVAL; + } + + if (L1SAP_IS_LINK_SACCH(link_id)) { + radio_link_timeout(lchan, 0); + le = &lchan->lapdm_ch.lapdm_acch; + /* save the SACCH L1 header in the lchan struct for RSL MEAS RES */ + if (len < 2) { + LOGP(DL1P, LOGL_NOTICE, "SACCH with size %u<2 !?!\n", + len); + return -EINVAL; + } + /* Some brilliant engineer decided that the ordering of + * fields on the Um interface is different from the + * order of fields in RLS. See TS 04.04 (Chapter 7.2) + * vs. TS 08.58 (Chapter 9.3.10). */ + lchan->meas.l1_info[0] = data[0] << 3; + lchan->meas.l1_info[0] |= ((data[0] >> 5) & 1) << 2; + lchan->meas.l1_info[1] = data[1]; + lchan->meas.flags |= LC_UL_M_F_L1_VALID; + } else + le = &lchan->lapdm_ch.lapdm_dcch; + + /* if this is the first valid message after enabling Rx + * decryption, we have to enable Tx encryption */ + if (lchan->ciph_state == LCHAN_CIPH_RX_CONF) { + /* HACK: check if it's an I frame, in order to + * ignore some still buffered/queued UI frames received + * before decryption was enabled */ + if (data[0] == 0x01 && (data[1] & 0x01) == 0) { + l1sap_tx_ciph_req(trx, chan_nr, 1, 0); + } + } + + /* SDCCH, SACCH and FACCH all go to LAPDm */ + msgb_pull(msg, (msg->l2h - msg->data)); + msg->l1h = NULL; + lapdm_phsap_up(&l1sap->oph, le); + + /* don't free, because we forwarded data */ + return 1; } /* TCH received from bts model */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index f17972b..6a6437e 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -464,7 +464,11 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, u32Fn = l1sap->u.data.fn; u8Tn = L1SAP_CHAN2TS(chan_nr); subCh = 0x1f; - if (L1SAP_IS_CHAN_TCHF(chan_nr)) { + if (L1SAP_IS_LINK_SACCH(link_id)) { + sapi = GsmL1_Sapi_Sacch; + if (!L1SAP_IS_CHAN_TCHF(chan_nr)) + subCh = l1sap_chan2ss(chan_nr); + } else if (L1SAP_IS_CHAN_TCHF(chan_nr)) { if (trx->ts[u8Tn].pchan == GSM_PCHAN_PDCH) { if (L1SAP_IS_PTCCH(u32Fn)) { sapi = GsmL1_Sapi_Ptcch; @@ -473,7 +477,20 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, sapi = GsmL1_Sapi_Pdtch; u8BlockNbr = L1SAP_FN2MACBLOCK(u32Fn); } + } else { + sapi = GsmL1_Sapi_FacchF; + u8BlockNbr = (u32Fn % 13) >> 2; } + } else if (L1SAP_IS_CHAN_TCHH(chan_nr)) { + subCh = L1SAP_CHAN2SS_TCHH(chan_nr); + sapi = GsmL1_Sapi_FacchH; + u8BlockNbr = (u32Fn % 26) >> 3; + } else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) { + subCh = L1SAP_CHAN2SS_SDCCH4(chan_nr); + sapi = GsmL1_Sapi_Sdcch; + } else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) { + subCh = L1SAP_CHAN2SS_SDCCH8(chan_nr); + sapi = GsmL1_Sapi_Sdcch; } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) { sapi = GsmL1_Sapi_Bcch; } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { @@ -603,12 +620,27 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, struct osmo_phsap_prim *l1sap) { + struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx); uint8_t u8Tn, ss; uint8_t chan_nr; struct gsm_lchan *lchan; int rc = 0; switch (l1sap->u.info.type) { + case PRIM_INFO_ACT_CIPH: + chan_nr = l1sap->u.info.u.ciph_req.chan_nr; + u8Tn = L1SAP_CHAN2TS(chan_nr); + ss = l1sap_chan2ss(chan_nr); + lchan = &trx->ts[u8Tn].lchan[ss]; + if (l1sap->u.info.u.ciph_req.uplink) { + l1if_set_ciphering(fl1, lchan, 0); + lchan->ciph_state = LCHAN_CIPH_RX_REQ; + } + if (l1sap->u.info.u.ciph_req.downlink) { + l1if_set_ciphering(fl1, lchan, 1); + lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; + } + break; case PRIM_INFO_ACTIVATE: case PRIM_INFO_DEACTIVATE: case PRIM_INFO_MODIFY: @@ -701,6 +733,40 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, case GsmL1_Sapi_Bcch: cbits = 0x10; break; + case GsmL1_Sapi_Sacch: + switch(pchan) { + case GSM_PCHAN_TCH_F: + cbits = 0x01; + break; + case GSM_PCHAN_TCH_H: + cbits = 0x02 + subCh; + break; + case GSM_PCHAN_CCCH_SDCCH4: + cbits = 0x04 + subCh; + break; + case GSM_PCHAN_SDCCH8_SACCH8C: + cbits = 0x08 + subCh; + break; + default: + LOGP(DL1C, LOGL_ERROR, "SACCH for pchan %d?\n", + pchan); + return 0; + } + break; + case GsmL1_Sapi_Sdcch: + switch(pchan) { + case GSM_PCHAN_CCCH_SDCCH4: + cbits = 0x04 + subCh; + break; + case GSM_PCHAN_SDCCH8_SACCH8C: + cbits = 0x08 + subCh; + break; + default: + LOGP(DL1C, LOGL_ERROR, "SDCCH for pchan %d?\n", + pchan); + return 0; + } + break; case GsmL1_Sapi_Agch: case GsmL1_Sapi_Pch: cbits = 0x12; @@ -723,6 +789,12 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan, case GsmL1_Sapi_TchH: cbits = 0x02 + subCh; break; + case GsmL1_Sapi_FacchF: + cbits = 0x01; + break; + case GsmL1_Sapi_FacchH: + cbits = 0x02 + subCh; + break; case GsmL1_Sapi_Ptcch: if (!L1SAP_IS_PTCCH(u32Fn)) { LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame " @@ -757,11 +829,8 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, struct msgb *resp_msg; GsmL1_PhDataReq_t *data_req; GsmL1_MsgUnitParam_t *msu_param; - struct lapdm_entity *le; - struct gsm_lchan *lchan; struct gsm_time g_time; uint32_t t3p; - struct osmo_phsap_prim pp; int rc; struct osmo_phsap_prim *l1sap; uint8_t chan_nr, link_id; @@ -772,7 +841,10 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, rts_ind->subCh, rts_ind->u8Tn, rts_ind->u32Fn); if (chan_nr) { fn = rts_ind->u32Fn; - link_id = 0; + if (rts_ind->sapi == GsmL1_Sapi_Sacch) + link_id = 0x40; + else + link_id = 0; rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive\n"); @@ -899,27 +971,6 @@ empty_frame: goto tx; } -/* determine LAPDm entity inside LAPDm channel for given L1 sapi */ -static struct lapdm_entity *le_by_l1_sapi(struct lapdm_channel *lc, GsmL1_Sapi_t sapi) -{ - switch (sapi) { - case GsmL1_Sapi_Sacch: - return &lc->lapdm_acch; - default: - return &lc->lapdm_dcch; - } -} - -static uint8_t gen_link_id(GsmL1_Sapi_t l1_sapi, uint8_t lapdm_sapi) -{ - uint8_t c_bits = 0; - - if (l1_sapi == GsmL1_Sapi_Sacch) - c_bits = 0x40; - - return c_bits | (lapdm_sapi & 7); -} - static void dump_meas_res(int ll, GsmL1_MeasParam_t *m) { LOGPC(DL1C, ll, ", Meas: RSSI %-3.2f dBm, Qual %-3.2f dB, " @@ -943,46 +994,11 @@ static int process_meas_res(struct gsm_lchan *lchan, GsmL1_MeasParam_t *m) return lchan_new_ul_meas(lchan, &ulm); } -/* process radio link timeout counter S */ -static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame) -{ - struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role; - - /* if link loss criterion already reached */ - if (lchan->s == 0) { - DEBUGP(DMEAS, "%s radio link counter S already 0.\n", - gsm_lchan_name(lchan)); - return; - } - - if (bad_frame) { - /* count down radio link counter S */ - lchan->s--; - DEBUGP(DMEAS, "%s counting down radio link counter S=%d\n", - gsm_lchan_name(lchan), lchan->s); - if (lchan->s == 0) - rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL); - return; - } - - if (lchan->s < btsb->radio_link_timeout) { - /* count up radio link counter S */ - lchan->s += 2; - if (lchan->s > btsb->radio_link_timeout) - lchan->s = btsb->radio_link_timeout; - DEBUGP(DMEAS, "%s counting up radio link counter S=%d\n", - gsm_lchan_name(lchan), lchan->s); - } -} - static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg) { struct gsm_bts_trx *trx = fl1->priv; - struct osmo_phsap_prim pp; struct gsm_lchan *lchan; - struct lapdm_entity *le; - struct msgb *msg; uint8_t chan_nr, link_id; struct osmo_phsap_prim *l1sap; uint32_t fn; @@ -1002,6 +1018,12 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i chan_nr = chan_nr_by_sapi(trx->ts[data_ind->u8Tn].pchan, data_ind->sapi, data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn); + if (!chan_nr) { + LOGP(DL1C, LOGL_ERROR, "PH-DATA-INDICATION for unknown sapi " + "%d\n", data_ind->sapi); + msgb_free(l1p_msg); + return ENOTSUP; + } fn = data_ind->u32Fn; link_id = (data_ind->sapi == GsmL1_Sapi_Sacch) ? 0x40 : 0x00; @@ -1023,84 +1045,15 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i if (lchan->ho.active == HANDOVER_WAIT_FRAME) handover_frame(lchan); - switch (data_ind->sapi) { - case GsmL1_Sapi_Sacch: - radio_link_timeout(lchan, (data_ind->msgUnitParam.u8Size == 0)); - if (data_ind->msgUnitParam.u8Size == 0) - break; - /* save the SACCH L1 header in the lchan struct for RSL MEAS RES */ - if (data_ind->msgUnitParam.u8Size < 2) { - LOGP(DL1C, LOGL_NOTICE, "SACCH with size %u<2 !?!\n", - data_ind->msgUnitParam.u8Size); - break; - } - /* Some brilliant engineer decided that the ordering of - * fields on the Um interface is different from the - * order of fields in RLS. See TS 04.04 (Chapter 7.2) - * vs. TS 08.58 (Chapter 9.3.10). */ - lchan->meas.l1_info[0] = data_ind->msgUnitParam.u8Buffer[0] << 3; - lchan->meas.l1_info[0] |= ((data_ind->msgUnitParam.u8Buffer[0] >> 5) & 1) << 2; - lchan->meas.l1_info[1] = data_ind->msgUnitParam.u8Buffer[1]; - lchan->meas.flags |= LC_UL_M_F_L1_VALID; - /* fall-through */ - case GsmL1_Sapi_Sdcch: - case GsmL1_Sapi_FacchF: - case GsmL1_Sapi_FacchH: - /* Check and Re-check for the SACCH */ - if (data_ind->msgUnitParam.u8Size == 0) { - LOGP(DL1C, LOGL_NOTICE, "%s %s data is null.\n", - gsm_lchan_name(lchan), - get_value_string(femtobts_l1sapi_names, data_ind->sapi)); - break; - } - - check_for_first_ciphrd(fl1, &data_ind->msgUnitParam, lchan); - - /* SDCCH, SACCH and FACCH all go to LAPDm */ - le = le_by_l1_sapi(&lchan->lapdm_ch, data_ind->sapi); - /* allocate and fill LAPDm primitive */ - msg = msgb_alloc_headroom(128, 64, "PH-DATA.ind"); - osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA, - PRIM_OP_INDICATION, msg); - - /* copy over actual MAC block */ - msg->l2h = msgb_put(msg, data_ind->msgUnitParam.u8Size); - memcpy(msg->l2h, data_ind->msgUnitParam.u8Buffer, - data_ind->msgUnitParam.u8Size); - - /* LAPDm requires those... */ - pp.u.data.chan_nr = gsm_lchan2chan_nr(lchan); - pp.u.data.link_id = gen_link_id(data_ind->sapi, 0); - - /* feed into the LAPDm code of libosmogsm */ - rc = lapdm_phsap_up(&pp.oph, le); - break; - case GsmL1_Sapi_TchF: - case GsmL1_Sapi_TchH: + /* check for TCH */ + if (data_ind->sapi == GsmL1_Sapi_TchF + || data_ind->sapi == GsmL1_Sapi_TchH) { /* TCH speech frame handling */ rc = l1if_tch_rx(trx, chan_nr, l1p_msg); - break; - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - case GsmL1_Sapi_Ptcch: - break; - case GsmL1_Sapi_Idle: - /* nothing to send */ - break; - default: - LOGP(DL1C, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n", - get_value_string(femtobts_l1sapi_names, data_ind->sapi)); - break; - } - - if (!chan_nr) { - /* message was handled by old code, not by L1SAP */ msgb_free(l1p_msg); return rc; } - /* if we proceed to this point, the message has to be handled via L1SAP */ - /* get data pointer and length */ data = data_ind->msgUnitParam.u8Buffer; len = data_ind->msgUnitParam.u8Size; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:44 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:44 +0200 Subject: [PATCH 25/33] sysmobts/l1_if: Sacch/Sdcc/Facch are handled in l1sap/core In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-26-git-send-email-laforge@gnumonks.org> --- src/osmo-bts-sysmo/l1_if.c | 55 ---------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 6a6437e..b62a2a3 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -892,61 +892,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, msu_param->u8Buffer[2] = (g_time.t1 << 7) | (g_time.t2 << 2) | (t3p >> 1); msu_param->u8Buffer[3] = (t3p & 1); break; - case GsmL1_Sapi_Sacch: - /* resolve the L2 entity using rts_ind->hLayer2 */ - lchan = l1if_hLayer_to_lchan(trx, rts_ind->hLayer2); - le = &lchan->lapdm_ch.lapdm_acch; - /* if the DSP is taking care of power control - * (ul_power_target==0), then this value will be - * overridden. */ - msu_param->u8Buffer[0] = lchan->ms_power; - msu_param->u8Buffer[1] = lchan->rqd_ta; - rc = lapdm_phsap_dequeue_prim(le, &pp); - if (rc < 0) { - /* No SACCH data from LAPDM pending, send SACCH filling */ - uint8_t *si = lchan_sacch_get(lchan); - if (si) { - /* +2 to not overwrite the ms_power/ta values */ - memcpy(msu_param->u8Buffer+2, si, GSM_MACBLOCK_LEN-2); - } else { - /* +2 to not overwrite the ms_power/ta values */ - memcpy(msu_param->u8Buffer+2, fill_frame, GSM_MACBLOCK_LEN-2); - } - } else { - /* +2 to not overwrite the ms_power/ta values */ - memcpy(msu_param->u8Buffer+2, pp.oph.msg->data + 2, GSM_MACBLOCK_LEN-2); - msgb_free(pp.oph.msg); - } - break; - case GsmL1_Sapi_Sdcch: - /* resolve the L2 entity using rts_ind->hLayer2 */ - lchan = l1if_hLayer_to_lchan(trx, rts_ind->hLayer2); - le = &lchan->lapdm_ch.lapdm_dcch; - rc = lapdm_phsap_dequeue_prim(le, &pp); - if (rc < 0) - memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); - else { - memcpy(msu_param->u8Buffer, pp.oph.msg->data, GSM_MACBLOCK_LEN); - /* check if it is a RR CIPH MODE CMD. if yes, enable RX ciphering */ - check_for_ciph_cmd(fl1, pp.oph.msg, lchan); - msgb_free(pp.oph.msg); - } - break; - case GsmL1_Sapi_FacchF: - case GsmL1_Sapi_FacchH: - /* resolve the L2 entity using rts_ind->hLayer2 */ - lchan = l1if_hLayer_to_lchan(trx, rts_ind->hLayer2); - le = &lchan->lapdm_ch.lapdm_dcch; - rc = lapdm_phsap_dequeue_prim(le, &pp); - if (rc < 0) - goto empty_frame; - else { - memcpy(msu_param->u8Buffer, pp.oph.msg->data, GSM_MACBLOCK_LEN); - /* check if it is a RR CIPH MODE CMD. if yes, enable RX ciphering */ - check_for_ciph_cmd(fl1, pp.oph.msg, lchan); - msgb_free(pp.oph.msg); - } - break; case GsmL1_Sapi_Prach: goto empty_frame; break; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:45 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:45 +0200 Subject: [PATCH 26/33] l1sap: Port code to new ciphering handling In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-27-git-send-email-laforge@gnumonks.org> ... introduced in 2cc37035d73191b71b9ba9c0d559a0da6a5f35e5 --- include/osmo-bts/l1sap.h | 2 ++ src/common/l1sap.c | 51 +++++++++++++++++++++++++++++++++--------- src/osmo-bts-sysmo/l1_if.c | 32 -------------------------- src/osmo-bts-sysmo/l1_if.h | 3 --- tests/sysmobts/sysmobts_test.c | 5 +++-- 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index dee430f..8165c81 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -68,4 +68,6 @@ extern uint8_t gsmtap_sapi_acch; #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) +void bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len, uint8_t chan_nr); #endif /* L1SAP_H */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 14dbde9..3f942e6 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -481,6 +481,46 @@ static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame) } } +static inline void check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len, + uint8_t chan_nr) +{ + uint8_t n_s; + + /* if this is the first valid message after enabling Rx + * decryption, we have to enable Tx encryption */ + if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) { + printf("ciph_State\n"); + return; + } + + /* HACK: check if it's an I frame, in order to + * ignore some still buffered/queued UI frames received + * before decryption was enabled */ + if (data[0] != 0x01) + return; + + if ((data[1] & 0x01) != 0) + return; + + n_s = data[1] >> 5; + if (lchan->ciph_ns != n_s) + return; + + lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; + + /* this check is only introduced to make the test work :/ */ + if (lchan->ts && lchan->ts->trx) + l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 1, 0); +} + +/* public helper for the test */ +void bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len, uint8_t chan_nr) +{ + return check_for_first_ciphrd(lchan, data, len, chan_nr); +} + /* DATA received from bts model */ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) @@ -557,16 +597,7 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, } else le = &lchan->lapdm_ch.lapdm_dcch; - /* if this is the first valid message after enabling Rx - * decryption, we have to enable Tx encryption */ - if (lchan->ciph_state == LCHAN_CIPH_RX_CONF) { - /* HACK: check if it's an I frame, in order to - * ignore some still buffered/queued UI frames received - * before decryption was enabled */ - if (data[0] == 0x01 && (data[1] & 0x01) == 0) { - l1sap_tx_ciph_req(trx, chan_nr, 1, 0); - } - } + check_for_first_ciphrd(lchan, data, len, chan_nr); /* SDCCH, SACCH and FACCH all go to LAPDm */ msgb_pull(msg, (msg->l2h - msg->data)); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index b62a2a3..14efc2c 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -356,31 +356,6 @@ static int check_for_ciph_cmd(struct femtol1_hdl *fl1h, return 1; } -static inline void check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan) -{ - uint8_t n_s; - - /* if this is the first valid message after enabling Rx - * decryption, we have to enable Tx encryption */ - if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) - return; - - /* HACK: check if it's an I frame, in order to - * ignore some still buffered/queued UI frames received - * before decryption was enabled */ - if (msgUnitParam->u8Buffer[0] != 0x01) - return; - if ((msgUnitParam->u8Buffer[1] & 0x01) != 0) - return; - n_s = msgUnitParam->u8Buffer[1] >> 5; - if (lchan->ciph_ns != n_s) - return; - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; - l1if_set_ciphering(fl1h, lchan, 1); -} - /* public helpers for the test */ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, struct msgb *msg, struct gsm_lchan *lchan) @@ -388,13 +363,6 @@ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, return check_for_ciph_cmd(fl1h, msg, lchan); } -void bts_check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan) -{ - return check_for_first_ciphrd(fl1h, msgUnitParam, lchan); -} - static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = { 0x03, 0x03, 0x01, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 6f58e95..a425776 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -138,7 +138,4 @@ int l1if_rf_clock_info_correct(struct femtol1_hdl *fl1h); /* public helpers for test */ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, struct msgb *msg, struct gsm_lchan *lchan); -void bts_check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan); #endif /* _FEMTO_L1_H */ diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c index acbc09c..d5035bd 100644 --- a/tests/sysmobts/sysmobts_test.c +++ b/tests/sysmobts/sysmobts_test.c @@ -18,6 +18,7 @@ */ #include +#include #include "femtobts.h" #include "l1_if.h" @@ -169,13 +170,13 @@ static void test_sysmobts_cipher(void) /* Handle message sent before ciphering was received */ memcpy(&unit.u8Buffer[0], too_early_classmark, ARRAY_SIZE(too_early_classmark)); unit.u8Size = ARRAY_SIZE(too_early_classmark); - bts_check_for_first_ciphrd(&fl1h, &unit, &lchan); + bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size, 0); OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_RX_CONF); /* Now send the first ciphered message */ memcpy(&unit.u8Buffer[0], first_ciphered_cipher_cmpl, ARRAY_SIZE(first_ciphered_cipher_cmpl)); unit.u8Size = ARRAY_SIZE(first_ciphered_cipher_cmpl); - bts_check_for_first_ciphrd(&fl1h, &unit, &lchan); + bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size, 0); OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_TXRX_REQ); } -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:46 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:46 +0200 Subject: [PATCH 27/33] Add MEAS (MPH_INFO) IND message to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-28-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg This part moves processing of measurement infos from osmo-bts-sysmo to common part. --- include/osmo-bts/l1sap.h | 4 +-- src/common/l1sap.c | 64 +++++++++++++++++++++++++++++------------- src/osmo-bts-sysmo/l1_if.c | 26 ++++++++--------- tests/sysmobts/sysmobts_test.c | 9 ++++-- 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 8165c81..e76aca6 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -68,6 +68,6 @@ extern uint8_t gsmtap_sapi_acch; #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) -void bts_check_for_first_ciphrd(struct gsm_lchan *lchan, - uint8_t *data, int len, uint8_t chan_nr); +int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len); #endif /* L1SAP_H */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3f942e6..f00c5d2 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -155,6 +155,35 @@ static int l1sap_info_time_ind(struct gsm_bts_trx *trx, return 0; } +/* measurement information received from bts model */ +static int l1sap_info_meas_ind(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_meas_ind_param *info_meas_ind) +{ + struct bts_ul_meas ulm; + struct gsm_lchan *lchan; + + DEBUGP(DL1P, "MPH_INFO meas ind chan_nr=%02x\n", + info_meas_ind->chan_nr); + + lchan = &trx->ts[L1SAP_CHAN2TS(info_meas_ind->chan_nr)] + .lchan[l1sap_chan2ss(info_meas_ind->chan_nr)]; + + /* in the GPRS case we are not interested in measurement + * processing. The PCU will take care of it */ + if (lchan->type == GSM_LCHAN_PDTCH) + return 0; + + memset(&ulm, 0, sizeof(ulm)); + ulm.ta_offs_qbits = info_meas_ind->ta_offs_qbits; + ulm.ber10k = info_meas_ind->ber10k; + ulm.inv_rssi = info_meas_ind->inv_rssi; + + lchan_new_ul_meas(lchan, &ulm); + + return 0; +} + /* any L1 MPH_INFO indication prim recevied from bts model */ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct mph_info_param *info) @@ -165,6 +194,9 @@ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, case PRIM_INFO_TIME: rc = l1sap_info_time_ind(trx, l1sap, &info->u.time_ind); break; + case PRIM_INFO_MEAS: + rc = l1sap_info_meas_ind(trx, l1sap, &info->u.meas_ind); + break; default: LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO ind type %d\n", info->type); @@ -481,44 +513,37 @@ static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame) } } -static inline void check_for_first_ciphrd(struct gsm_lchan *lchan, - uint8_t *data, int len, - uint8_t chan_nr) +static inline int check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len) { uint8_t n_s; /* if this is the first valid message after enabling Rx * decryption, we have to enable Tx encryption */ - if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) { - printf("ciph_State\n"); - return; - } + if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) + return 0; /* HACK: check if it's an I frame, in order to * ignore some still buffered/queued UI frames received * before decryption was enabled */ if (data[0] != 0x01) - return; + return 0; if ((data[1] & 0x01) != 0) - return; + return 0; n_s = data[1] >> 5; if (lchan->ciph_ns != n_s) - return; - - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; + return 0; - /* this check is only introduced to make the test work :/ */ - if (lchan->ts && lchan->ts->trx) - l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 1, 0); + return 1; } /* public helper for the test */ -void bts_check_for_first_ciphrd(struct gsm_lchan *lchan, - uint8_t *data, int len, uint8_t chan_nr) +int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len) { - return check_for_first_ciphrd(lchan, data, len, chan_nr); + return check_for_first_ciphrd(lchan, data, len); } /* DATA received from bts model */ @@ -597,7 +622,8 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, } else le = &lchan->lapdm_ch.lapdm_dcch; - check_for_first_ciphrd(lchan, data, len, chan_nr); + if (check_for_first_ciphrd(lchan, data, len)) + l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 0, 1); /* SDCCH, SACCH and FACCH all go to LAPDm */ msgb_pull(msg, (msg->l2h - msg->data)); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 14efc2c..38daa97 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -891,20 +891,20 @@ static void dump_meas_res(int ll, GsmL1_MeasParam_t *m) m->fBer, m->i16BurstTiming); } -static int process_meas_res(struct gsm_lchan *lchan, GsmL1_MeasParam_t *m) +static int process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr, + GsmL1_MeasParam_t *m) { - struct bts_ul_meas ulm; - - /* in the GPRS case we are not interested in measurement - * processing. The PCU will take care of it */ - if (lchan->type == GSM_LCHAN_PDTCH) - return 0; - - ulm.ta_offs_qbits = m->i16BurstTiming; - ulm.ber10k = (unsigned int) (m->fBer * 100); - ulm.inv_rssi = (uint8_t) (m->fRssi * -1); + struct osmo_phsap_prim l1sap; + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, + PRIM_OP_INDICATION, NULL); + l1sap.u.info.type = PRIM_INFO_MEAS; + l1sap.u.info.u.meas_ind.chan_nr = chan_nr; + l1sap.u.info.u.meas_ind.ta_offs_qbits = m->i16BurstTiming; + l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 100); + l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1); - return lchan_new_ul_meas(lchan, &ulm); + return l1sap_up(trx, &l1sap); } static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind, @@ -940,7 +940,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i fn = data_ind->u32Fn; link_id = (data_ind->sapi == GsmL1_Sapi_Sacch) ? 0x40 : 0x00; - process_meas_res(lchan, &data_ind->measParam); + process_meas_res(trx, chan_nr, &data_ind->measParam); if (data_ind->measParam.fLinkQuality < fl1->min_qual_norm && data_ind->msgUnitParam.u8Size != 0) { diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c index d5035bd..93fa0e9 100644 --- a/tests/sysmobts/sysmobts_test.c +++ b/tests/sysmobts/sysmobts_test.c @@ -170,14 +170,17 @@ static void test_sysmobts_cipher(void) /* Handle message sent before ciphering was received */ memcpy(&unit.u8Buffer[0], too_early_classmark, ARRAY_SIZE(too_early_classmark)); unit.u8Size = ARRAY_SIZE(too_early_classmark); - bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size, 0); + rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size); + OSMO_ASSERT(rc == 0); OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_RX_CONF); /* Now send the first ciphered message */ memcpy(&unit.u8Buffer[0], first_ciphered_cipher_cmpl, ARRAY_SIZE(first_ciphered_cipher_cmpl)); unit.u8Size = ARRAY_SIZE(first_ciphered_cipher_cmpl); - bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size, 0); - OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_TXRX_REQ); + rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size); + OSMO_ASSERT(rc == 1); + /* we cannot test for lchan.ciph_state == LCHAN_CIPH_RX_CONF_TX_REQ, as + * this happens asynchronously on the other side of the l1sap queue */ } int main(int argc, char **argv) -- 2.1.0 From holger at freyther.de Thu Aug 28 12:01:30 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 28 Aug 2014 14:01:30 +0200 Subject: [PATCH 27/33] Add MEAS (MPH_INFO) IND message to PH-/MPH-/TCH-SAP interface In-Reply-To: <1409176492-13269-28-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <1409176492-13269-28-git-send-email-laforge@gnumonks.org> Message-ID: <20140828120130.GC3508@xiaoyu.lan> On Wed, Aug 27, 2014 at 11:54:46PM +0200, Harald Welte wrote: > +static inline int check_for_first_ciphrd(struct gsm_lchan *lchan, > + uint8_t *data, int len) > { > - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; this looks to belong to a different patch?! From laforge at gnumonks.org Thu Aug 28 13:19:52 2014 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 28 Aug 2014 15:19:52 +0200 Subject: [PATCH 27/33] Add MEAS (MPH_INFO) IND message to PH-/MPH-/TCH-SAP interface In-Reply-To: <20140828120130.GC3508@xiaoyu.lan> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <1409176492-13269-28-git-send-email-laforge@gnumonks.org> <20140828120130.GC3508@xiaoyu.lan> Message-ID: <20140828131952.GA12087@nataraja> Hi Holger, On Thu, Aug 28, 2014 at 02:01:30PM +0200, Holger Hans Peter Freyther wrote: > > - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; > > this looks to belong to a different patch?! Indeed, I accidentially squashed two wrong commits. I've fixed it. The two affected patcheas are patch 26 and 27 of the series, new commits are: 69eba91fdc97f042f72049a754f0162c9c289f45 and 0fa6dc976b41757c95c587989185b5bb55d17fdf attached for your reference (rather than spamming the list with the entire series again). -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From laforge at gnumonks.org Wed Aug 27 20:13:18 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 22:13:18 +0200 Subject: [PATCH 1/8] l1sap: Port code to new ciphering handling Message-ID: ... introduced in 2cc37035d73191b71b9ba9c0d559a0da6a5f35e5 --- include/osmo-bts/l1sap.h | 2 ++ src/common/l1sap.c | 45 ++++++++++++++++++++++++++++++++---------- src/osmo-bts-sysmo/l1_if.c | 32 ------------------------------ src/osmo-bts-sysmo/l1_if.h | 3 --- tests/sysmobts/sysmobts_test.c | 10 +++++++--- 5 files changed, 44 insertions(+), 48 deletions(-) diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index dee430f..e76aca6 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -68,4 +68,6 @@ extern uint8_t gsmtap_sapi_acch; #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) +int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len); #endif /* L1SAP_H */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 14dbde9..9c7a9c6 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -481,6 +481,39 @@ static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame) } } +static inline int check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len) +{ + uint8_t n_s; + + /* if this is the first valid message after enabling Rx + * decryption, we have to enable Tx encryption */ + if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) + return 0; + + /* HACK: check if it's an I frame, in order to + * ignore some still buffered/queued UI frames received + * before decryption was enabled */ + if (data[0] != 0x01) + return 0; + + if ((data[1] & 0x01) != 0) + return 0; + + n_s = data[1] >> 5; + if (lchan->ciph_ns != n_s) + return 0; + + return 1; +} + +/* public helper for the test */ +int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, + uint8_t *data, int len) +{ + return check_for_first_ciphrd(lchan, data, len); +} + /* DATA received from bts model */ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) @@ -557,16 +590,8 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, } else le = &lchan->lapdm_ch.lapdm_dcch; - /* if this is the first valid message after enabling Rx - * decryption, we have to enable Tx encryption */ - if (lchan->ciph_state == LCHAN_CIPH_RX_CONF) { - /* HACK: check if it's an I frame, in order to - * ignore some still buffered/queued UI frames received - * before decryption was enabled */ - if (data[0] == 0x01 && (data[1] & 0x01) == 0) { - l1sap_tx_ciph_req(trx, chan_nr, 1, 0); - } - } + if (check_for_first_ciphrd(lchan, data, len)) + l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 1, 0); /* SDCCH, SACCH and FACCH all go to LAPDm */ msgb_pull(msg, (msg->l2h - msg->data)); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index b62a2a3..14efc2c 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -356,31 +356,6 @@ static int check_for_ciph_cmd(struct femtol1_hdl *fl1h, return 1; } -static inline void check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan) -{ - uint8_t n_s; - - /* if this is the first valid message after enabling Rx - * decryption, we have to enable Tx encryption */ - if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) - return; - - /* HACK: check if it's an I frame, in order to - * ignore some still buffered/queued UI frames received - * before decryption was enabled */ - if (msgUnitParam->u8Buffer[0] != 0x01) - return; - if ((msgUnitParam->u8Buffer[1] & 0x01) != 0) - return; - n_s = msgUnitParam->u8Buffer[1] >> 5; - if (lchan->ciph_ns != n_s) - return; - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; - l1if_set_ciphering(fl1h, lchan, 1); -} - /* public helpers for the test */ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, struct msgb *msg, struct gsm_lchan *lchan) @@ -388,13 +363,6 @@ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, return check_for_ciph_cmd(fl1h, msg, lchan); } -void bts_check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan) -{ - return check_for_first_ciphrd(fl1h, msgUnitParam, lchan); -} - static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = { 0x03, 0x03, 0x01, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 6f58e95..a425776 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -138,7 +138,4 @@ int l1if_rf_clock_info_correct(struct femtol1_hdl *fl1h); /* public helpers for test */ int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h, struct msgb *msg, struct gsm_lchan *lchan); -void bts_check_for_first_ciphrd(struct femtol1_hdl *fl1h, - GsmL1_MsgUnitParam_t *msgUnitParam, - struct gsm_lchan *lchan); #endif /* _FEMTO_L1_H */ diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c index acbc09c..3ed78fd 100644 --- a/tests/sysmobts/sysmobts_test.c +++ b/tests/sysmobts/sysmobts_test.c @@ -18,6 +18,7 @@ */ #include +#include #include "femtobts.h" #include "l1_if.h" @@ -169,14 +170,17 @@ static void test_sysmobts_cipher(void) /* Handle message sent before ciphering was received */ memcpy(&unit.u8Buffer[0], too_early_classmark, ARRAY_SIZE(too_early_classmark)); unit.u8Size = ARRAY_SIZE(too_early_classmark); - bts_check_for_first_ciphrd(&fl1h, &unit, &lchan); + rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size); + OSMO_ASSERT(rc == 0); OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_RX_CONF); /* Now send the first ciphered message */ memcpy(&unit.u8Buffer[0], first_ciphered_cipher_cmpl, ARRAY_SIZE(first_ciphered_cipher_cmpl)); unit.u8Size = ARRAY_SIZE(first_ciphered_cipher_cmpl); - bts_check_for_first_ciphrd(&fl1h, &unit, &lchan); - OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_TXRX_REQ); + rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size); + OSMO_ASSERT(rc == 1); + /* we cannot test for lchan.ciph_state == * LCHAN_CIPH_RX_CONF_TX_REQ, as + * this happens asynchronously on the other side of the l1sap queue */ } int main(int argc, char **argv) -- 2.1.0 --PMULwz+zIGJzpDN9 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0002-Add-MEAS-MPH_INFO-IND-message-to-PH-MPH-TCH-SAP-inte.patch" From laforge at gnumonks.org Wed Aug 27 21:54:47 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:47 +0200 Subject: [PATCH 28/33] sysmobts: Clean up transitions for lchan cipher state In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-29-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg There are three transitions: 1. LCHAN_CIPH_NONE -> LCHAN_CIPH_RX_REQ -> LCHAN_CIPH_RX_CONF It is used to enable ciphering in RX (uplink) direction only. 2. LCHAN_CIPH_RX_CONF -> LCHAN_CIPH_RX_CONF_TX_REQ -> LCHAN_CIPH_RXTX_CONF It is used to additionally enable ciphering in TX (downlink) direction. 3. LCHAN_CIPH_NONE -> LCHAN_CIPH_RXTX_REQ -> LCHAN_CIPH_RX_CONF_TX_REQ -> LCHAN_CIPH_RXTX_CONF It is used to enable ciphering in both TX and RX directions. This is used when the channel is activated with encryption already enabled. (assignment or handover) In order to follow the order of these transitions, the RX direction must always be set before the TX direction. If no cipher key is set (A5/0), ciphering is set to ALG 0, but lchan cipher state remains at LCHAN_CIPH_NONE. --- include/osmo-bts/gsm_data.h | 5 +++-- src/common/l1sap.c | 1 - src/osmo-bts-sysmo/l1_if.c | 5 ++++- src/osmo-bts-sysmo/oml.c | 19 +++++++++++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index c6866a3..bd726e2 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -91,8 +91,9 @@ enum lchan_ciph_state { LCHAN_CIPH_NONE, LCHAN_CIPH_RX_REQ, LCHAN_CIPH_RX_CONF, - LCHAN_CIPH_TXRX_REQ, - LCHAN_CIPH_TXRX_CONF, + LCHAN_CIPH_RXTX_REQ, + LCHAN_CIPH_RX_CONF_TX_REQ, + LCHAN_CIPH_RXTX_CONF, }; #define bts_role_bts(x) ((struct gsm_bts_role_bts *)(x)->role) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index f00c5d2..3f099b0 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -96,7 +96,6 @@ static int check_for_ciph_cmd(struct msgb *msg, struct gsm_lchan *lchan, /* only do this if we are in the right state */ switch (lchan->ciph_state) { case LCHAN_CIPH_NONE: - case LCHAN_CIPH_RX_REQ: break; default: return 0; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 38daa97..b4ae300 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -606,8 +606,11 @@ static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, } if (l1sap->u.info.u.ciph_req.downlink) { l1if_set_ciphering(fl1, lchan, 1); - lchan->ciph_state = LCHAN_CIPH_TXRX_REQ; + lchan->ciph_state = LCHAN_CIPH_RX_CONF_TX_REQ; } + if (l1sap->u.info.u.ciph_req.downlink + && l1sap->u.info.u.ciph_req.uplink) + lchan->ciph_state = LCHAN_CIPH_RXTX_REQ; break; case PRIM_INFO_ACTIVATE: case PRIM_INFO_DEACTIVATE: diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index f490195..dc8a625 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -980,8 +980,12 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, 0); /* set the initial ciphering parameters for both directions */ - l1if_set_ciphering(fl1h, lchan, 0); l1if_set_ciphering(fl1h, lchan, 1); + l1if_set_ciphering(fl1h, lchan, 0); + if (lchan->encr.alg_id) + lchan->ciph_state = LCHAN_CIPH_RXTX_REQ; + else + lchan->ciph_state = LCHAN_CIPH_NONE; return 0; } @@ -1130,9 +1134,16 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, LOGPC(DL1C, LOGL_INFO, "RX_REQ -> RX_CONF\n"); lchan->ciph_state = LCHAN_CIPH_RX_CONF; break; - case LCHAN_CIPH_TXRX_REQ: - LOGPC(DL1C, LOGL_INFO, "TX_REQ -> TX_CONF\n"); - lchan->ciph_state = LCHAN_CIPH_TXRX_CONF; + case LCHAN_CIPH_RX_CONF_TX_REQ: + LOGPC(DL1C, LOGL_INFO, "RX_CONF_TX_REQ -> RXTX_CONF\n"); + lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; + break; + case LCHAN_CIPH_RXTX_REQ: + LOGPC(DL1C, LOGL_INFO, "RXTX_REQ -> RX_CONF_TX_REQ\n"); + lchan->ciph_state = LCHAN_CIPH_RX_CONF_TX_REQ; + break; + case LCHAN_CIPH_NONE: + LOGPC(DL1C, LOGL_INFO, "\n"); break; default: LOGPC(DL1C, LOGL_INFO, "unhandled state %u\n", lchan->ciph_state); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:48 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:48 +0200 Subject: [PATCH 29/33] Send primitives at PH-/MPH-/TCH-SAP interface via GSMTAP In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-30-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- src/common/l1sap.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3f099b0..e006412 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -116,6 +116,167 @@ static int check_for_ciph_cmd(struct msgb *msg, struct gsm_lchan *lchan, return 1; } +struct gsmtap_inst *gsmtap = NULL; +uint32_t gsmtap_sapi_mask = 0; +uint8_t gsmtap_sapi_acch = 0; + +const struct value_string gsmtap_sapi_names[] = { + { GSMTAP_CHANNEL_BCCH, "BCCH" }, + { GSMTAP_CHANNEL_CCCH, "CCCH" }, + { GSMTAP_CHANNEL_RACH, "RACH" }, + { GSMTAP_CHANNEL_AGCH, "AGCH" }, + { GSMTAP_CHANNEL_PCH, "PCH" }, + { GSMTAP_CHANNEL_SDCCH, "SDCCH" }, + { GSMTAP_CHANNEL_TCH_F, "TCH/F" }, + { GSMTAP_CHANNEL_TCH_H, "TCH/H" }, + { GSMTAP_CHANNEL_PACCH, "PACCH" }, + { GSMTAP_CHANNEL_PDCH, "PDTCH" }, + { GSMTAP_CHANNEL_PTCCH, "PTCCH" }, + { GSMTAP_CHANNEL_CBCH51,"CBCH" }, + { GSMTAP_CHANNEL_ACCH, "SACCH" }, + { 0, NULL } +}; + +/* send primitive as gsmtap */ +static int gsmtap_ph_data(struct osmo_phsap_prim *l1sap, uint8_t *chan_type, + uint8_t *tn, uint8_t *ss, uint32_t *fn, uint8_t **data, int *len) +{ + struct msgb *msg = l1sap->oph.msg; + uint8_t chan_nr, link_id; + + *data = msg->data + sizeof(struct osmo_phsap_prim); + *len = msg->len - sizeof(struct osmo_phsap_prim); + *fn = l1sap->u.data.fn; + *tn = L1SAP_CHAN2TS(l1sap->u.data.chan_nr); + chan_nr = l1sap->u.data.chan_nr; + link_id = l1sap->u.data.link_id; + + if (L1SAP_IS_CHAN_TCHF(chan_nr)) { + *chan_type = GSMTAP_CHANNEL_TCH_F; + } else if (L1SAP_IS_CHAN_TCHH(chan_nr)) { + *ss = L1SAP_CHAN2SS_TCHH(chan_nr); + *chan_type = GSMTAP_CHANNEL_TCH_H; + } else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) { + *ss = L1SAP_CHAN2SS_SDCCH4(chan_nr); + *chan_type = GSMTAP_CHANNEL_SDCCH; + } else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) { + *ss = L1SAP_CHAN2SS_SDCCH8(chan_nr); + *chan_type = GSMTAP_CHANNEL_SDCCH; + } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) { + *chan_type = GSMTAP_CHANNEL_BCCH; + } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { +#warning Set BS_AG_BLKS_RES + /* The sapi depends on DSP configuration, not + * on the actual SYSTEM INFORMATION 3. */ + if (L1SAP_FN2CCCHBLOCK(*fn) >= 1) + *chan_type = GSMTAP_CHANNEL_PCH; + else + *chan_type = GSMTAP_CHANNEL_AGCH; + } + if (L1SAP_IS_LINK_SACCH(link_id)) + *chan_type |= GSMTAP_CHANNEL_ACCH; + + return 0; +} + +static int gsmtap_pdch(struct osmo_phsap_prim *l1sap, uint8_t *chan_type, + uint8_t *tn, uint8_t *ss, uint32_t *fn, uint8_t **data, int *len) +{ + struct msgb *msg = l1sap->oph.msg; + + *data = msg->data + sizeof(struct osmo_phsap_prim); + *len = msg->len - sizeof(struct osmo_phsap_prim); + *fn = l1sap->u.data.fn; + *tn = L1SAP_CHAN2TS(l1sap->u.data.chan_nr); + + if (L1SAP_IS_PTCCH(*fn)) { + *chan_type = GSMTAP_CHANNEL_PTCCH; + *ss = L1SAP_FN2PTCCHBLOCK(*fn); + if (l1sap->oph.primitive + == PRIM_OP_INDICATION) { + if ((*data[0]) == 7) + return -EINVAL; + (*data)++; + (*len)--; + } + } else + *chan_type = GSMTAP_CHANNEL_PACCH; + + return 0; +} + +static int gsmtap_ph_rach(struct osmo_phsap_prim *l1sap, uint8_t *chan_type, + uint8_t *tn, uint8_t *ss, uint32_t *fn, uint8_t **data, int *len) +{ + uint8_t chan_nr; + + *chan_type = GSMTAP_CHANNEL_RACH; + *fn = l1sap->u.rach_ind.fn; + *tn = L1SAP_CHAN2TS(l1sap->u.rach_ind.chan_nr); + chan_nr = l1sap->u.rach_ind.chan_nr; + if (L1SAP_IS_CHAN_TCHH(chan_nr)) + *ss = L1SAP_CHAN2SS_TCHH(chan_nr); + else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) + *ss = L1SAP_CHAN2SS_SDCCH4(chan_nr); + else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) + *ss = L1SAP_CHAN2SS_SDCCH8(chan_nr); + *data = &l1sap->u.rach_ind.ra; + *len = 1; + + return 0; +} + +static int to_gsmtap(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) +{ + uint8_t *data; + int len; + uint8_t chan_type = 0, tn = 0, ss = 0; + uint32_t fn; + uint16_t uplink = GSMTAP_ARFCN_F_UPLINK; + int rc; + + if (!gsmtap) + return 0; + + switch (OSMO_PRIM_HDR(&l1sap->oph)) { + case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): + uplink = 0; + /* fall through */ + case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_INDICATION): + if (trx->ts[tn].pchan == GSM_PCHAN_PDCH) + rc = gsmtap_pdch(l1sap, &chan_type, &tn, &ss, &fn, &data, + &len); + else + rc = gsmtap_ph_data(l1sap, &chan_type, &tn, &ss, &fn, + &data, &len); + break; + case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION): + rc = gsmtap_ph_rach(l1sap, &chan_type, &tn, &ss, &fn, &data, + &len); + break; + default: + rc = -ENOTSUP; + } + + if (rc) + return rc; + + if (len == 0) + return 0; + if ((chan_type & GSMTAP_CHANNEL_ACCH)) { + if (!gsmtap_sapi_acch) + return 0; + } else { + if (!((1 << (chan_type & 31)) & gsmtap_sapi_mask)) + return 0; + } + + gsmtap_send(gsmtap, trx->arfcn | uplink, tn, chan_type, ss, fn, 0, 0, + data, len); + + return 0; +} + /* time information received from bts model */ static int l1sap_info_time_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, @@ -743,12 +904,14 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) rc = l1sap_tch_rts_ind(trx, l1sap, &l1sap->u.tch); break; case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_INDICATION): + to_gsmtap(trx, l1sap); rc = l1sap_ph_data_ind(trx, l1sap, &l1sap->u.data); break; case OSMO_PRIM(PRIM_TCH, PRIM_OP_INDICATION): rc = l1sap_tch_ind(trx, l1sap, &l1sap->u.tch); break; case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION): + to_gsmtap(trx, l1sap); rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind); break; default: @@ -767,6 +930,10 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) /* any L1 prim sent to bts model */ static int l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) { + if (OSMO_PRIM_HDR(&l1sap->oph) == + OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST)) + to_gsmtap(trx, l1sap); + return bts_model_l1sap_down(trx, l1sap); } -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:49 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:49 +0200 Subject: [PATCH 30/33] Move gsmtap VTY commands from osmo-bts-sysmo to common part In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-31-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- include/osmo-bts/vty.h | 2 +- src/common/vty.c | 129 +++++++++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/main.c | 4 +- src/osmo-bts-sysmo/sysmobts_vty.c | 80 ----------------------- 4 files changed, 130 insertions(+), 85 deletions(-) diff --git a/include/osmo-bts/vty.h b/include/osmo-bts/vty.h index 1bc7e71..510abab 100644 --- a/include/osmo-bts/vty.h +++ b/include/osmo-bts/vty.h @@ -15,7 +15,7 @@ extern struct cmd_element ournode_end_cmd; enum node_type bts_vty_go_parent(struct vty *vty); int bts_vty_is_config_node(struct vty *vty, int node); -int bts_vty_init(const struct log_info *cat); +int bts_vty_init(struct gsm_bts *bts, const struct log_info *cat); extern struct vty_app_info bts_vty_info; diff --git a/src/common/vty.c b/src/common/vty.c index 6b57b0b..37f75fc 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -24,12 +24,15 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include @@ -44,7 +47,7 @@ #include #include #include - +#include enum node_type bts_vty_go_parent(struct vty *vty) { @@ -158,10 +161,38 @@ DEFUN(cfg_bts_trx, cfg_bts_trx_cmd, return CMD_SUCCESS; } +/* FIXME: move to libosmocore ? */ +static char buf_casecnvt[256]; +char *osmo_str_tolower(const char *in) +{ + int len, i; + + if (!in) + return NULL; + + len = strlen(in); + if (len > sizeof(buf_casecnvt)) + len = sizeof(buf_casecnvt); + + for (i = 0; i < len; i++) { + buf_casecnvt[i] = tolower(in[i]); + if (in[i] == '\0') + break; + } + if (i < sizeof(buf_casecnvt)) + buf_casecnvt[i] = '\0'; + + /* just to make sure we're always zero-terminated */ + buf_casecnvt[sizeof(buf_casecnvt)-1] = '\0'; + + return buf_casecnvt; +} + static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_bts_trx *trx; + int i; vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE); if (bts->description) @@ -183,6 +214,17 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) btsb->agch_queue_thresh_level, btsb->agch_queue_low_level, btsb->agch_queue_high_level, VTY_NEWLINE); + for (i = 0; i < 32; i++) { + if (gsmtap_sapi_mask & (1 << i)) { + const char *name = get_value_string(gsmtap_sapi_names, i); + vty_out(vty, " gsmtap-sapi %s%s", osmo_str_tolower(name), VTY_NEWLINE); + } + } + if (gsmtap_sapi_acch) { + const char *name = get_value_string(gsmtap_sapi_names, GSMTAP_CHANNEL_ACCH); + vty_out(vty, " gsmtap-sapi %s%s", osmo_str_tolower(name), VTY_NEWLINE); + } + bts_model_config_write_bts(vty, bts); llist_for_each_entry(trx, &bts->trx_list, list) { @@ -588,6 +630,36 @@ static struct gsm_lchan *resolve_lchan(struct gsm_network *net, "logical channel commands\n" \ "logical channel number\n" +DEFUN(cfg_trx_gsmtap_sapi, cfg_trx_gsmtap_sapi_cmd, + "HIDDEN", "HIDDEN") +{ + int sapi; + + sapi = get_string_value(gsmtap_sapi_names, argv[0]); + + if (sapi == GSMTAP_CHANNEL_ACCH) + gsmtap_sapi_acch = 1; + else + gsmtap_sapi_mask |= (1 << sapi); + + return CMD_SUCCESS; +} + +DEFUN(cfg_trx_no_gsmtap_sapi, cfg_trx_no_gsmtap_sapi_cmd, + "HIDDEN", "HIDDEN") +{ + int sapi; + + sapi = get_string_value(gsmtap_sapi_names, argv[0]); + + if (sapi == GSMTAP_CHANNEL_ACCH) + gsmtap_sapi_acch = 0; + else + gsmtap_sapi_mask &= ~(1 << sapi); + + return CMD_SUCCESS; +} + DEFUN(bts_t_t_l_jitter_buf, bts_t_t_l_jitter_buf_cmd, "bts <0-0> trx <0-0> ts <0-7> lchan <0-1> rtp jitter-buffer <0-10000>", @@ -614,8 +686,58 @@ DEFUN(bts_t_t_l_jitter_buf, return CMD_SUCCESS; } -int bts_vty_init(const struct log_info *cat) +DEFUN(bts_t_t_l_loopback, + bts_t_t_l_loopback_cmd, + "bts <0-0> trx <0-0> ts <0-7> lchan <0-1> loopback", + BTS_T_T_L_STR "Set loopback\n") { + struct gsm_network *net = gsmnet_from_vty(vty); + struct gsm_lchan *lchan; + + lchan = resolve_lchan(net, argv, 0); + if (!lchan) { + vty_out(vty, "%% can't find BTS%s", VTY_NEWLINE); + return CMD_WARNING; + } + lchan->loopback = 1; + + return CMD_SUCCESS; +} + +DEFUN(no_bts_t_t_l_loopback, + no_bts_t_t_l_loopback_cmd, + "no bts <0-0> trx <0-0> ts <0-7> lchan <0-1> loopback", + NO_STR BTS_T_T_L_STR "Set loopback\n") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + struct gsm_lchan *lchan; + + lchan = resolve_lchan(net, argv, 0); + if (!lchan) { + vty_out(vty, "%% can't find BTS%s", VTY_NEWLINE); + return CMD_WARNING; + } + lchan->loopback = 0; + + return CMD_SUCCESS; +} + +int bts_vty_init(struct gsm_bts *bts, const struct log_info *cat) +{ + cfg_trx_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names, + "gsmtap-sapi (", + "|",")", VTY_DO_LOWER); + cfg_trx_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names, + "GSMTAP SAPI\n", + "\n", "", 0); + + cfg_trx_no_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names, + "no gsmtap-sapi (", + "|",")", VTY_DO_LOWER); + cfg_trx_no_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names, + NO_STR "GSMTAP SAPI\n", + "\n", "", 0); + install_element_ve(&show_bts_cmd); logging_vty_add_cmds(cat); @@ -635,6 +757,9 @@ int bts_vty_init(const struct log_info *cat) install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_default_cmd); install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_params_cmd); + install_element(BTS_NODE, &cfg_trx_gsmtap_sapi_cmd); + install_element(BTS_NODE, &cfg_trx_no_gsmtap_sapi_cmd); + /* add and link to TRX config node */ install_element(BTS_NODE, &cfg_bts_trx_cmd); install_node(&trx_node, config_write_dummy); diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 51619ee..27b593b 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -310,8 +310,9 @@ int main(int argc, char **argv) bts_log_init(NULL); + bts = gsm_bts_alloc(tall_bts_ctx); vty_init(&bts_vty_info); - bts_vty_init(&bts_log_info); + bts_vty_init(bts, &bts_log_info); handle_options(argc, argv); @@ -327,7 +328,6 @@ int main(int argc, char **argv) } } - bts = gsm_bts_alloc(tall_bts_ctx); if (bts_init(bts) < 0) { fprintf(stderr, "unable to open bts\n"); exit(1); diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c index 8b617d7..cad29f5 100644 --- a/src/osmo-bts-sysmo/sysmobts_vty.c +++ b/src/osmo-bts-sysmo/sysmobts_vty.c @@ -84,34 +84,6 @@ DEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd, return CMD_SUCCESS; } -DEFUN(cfg_trx_gsmtap_sapi, cfg_trx_gsmtap_sapi_cmd, - "HIDDEN", "HIDDEN") -{ - struct gsm_bts_trx *trx = vty->index; - struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - int sapi; - - sapi = get_string_value(femtobts_l1sapi_names, argv[0]); - - fl1h->gsmtap_sapi_mask |= (1 << sapi); - - return CMD_SUCCESS; -} - -DEFUN(cfg_trx_no_gsmtap_sapi, cfg_trx_no_gsmtap_sapi_cmd, - "HIDDEN", "HIDDEN") -{ - struct gsm_bts_trx *trx = vty->index; - struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - int sapi; - - sapi = get_string_value(femtobts_l1sapi_names, argv[0]); - - fl1h->gsmtap_sapi_mask &= ~(1 << sapi); - - return CMD_SUCCESS; -} - DEFUN(cfg_trx_clkcal_eeprom, cfg_trx_clkcal_eeprom_cmd, "clock-calibration eeprom", "Use the eeprom clock calibration value\n") @@ -497,37 +469,9 @@ void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts) vty_out(vty, " auto-band%s", VTY_NEWLINE); } -/* FIXME: move to libosmocore ? */ -static char buf_casecnvt[256]; -char *osmo_str_tolower(const char *in) -{ - int len, i; - - if (!in) - return NULL; - - len = strlen(in); - if (len > sizeof(buf_casecnvt)) - len = sizeof(buf_casecnvt); - - for (i = 0; i < len; i++) { - buf_casecnvt[i] = tolower(in[i]); - if (in[i] == '\0') - break; - } - if (i < sizeof(buf_casecnvt)) - buf_casecnvt[i] = '\0'; - - /* just to make sure we're always zero-terminated */ - buf_casecnvt[sizeof(buf_casecnvt)-1] = '\0'; - - return buf_casecnvt; -} - void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) { struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - int i; if (fl1h->clk_use_eeprom) vty_out(vty, " clock-calibration eeprom%s", VTY_NEWLINE); @@ -549,14 +493,6 @@ void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) if (trx->nominal_power != sysmobts_get_nominal_power(trx)) vty_out(vty, " nominal-tx-power %d%s", trx->nominal_power, VTY_NEWLINE); - - for (i = 0; i < 32; i++) { - if (fl1h->gsmtap_sapi_mask & (1 << i)) { - const char *name = get_value_string(femtobts_l1sapi_names, i); - vty_out(vty, " gsmtap-sapi %s%s", osmo_str_tolower(name), - VTY_NEWLINE); - } - } } int bts_model_vty_init(struct gsm_bts *bts) @@ -578,20 +514,6 @@ int bts_model_vty_init(struct gsm_bts *bts) NO_STR TRX_STR DSP_TRACE_F_STR, "\n", "", 0); - cfg_trx_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, femtobts_l1sapi_names, - "gsmtap-sapi (", - "|",")", VTY_DO_LOWER); - cfg_trx_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, femtobts_l1sapi_names, - "GSMTAP SAPI\n", - "\n", "", 0); - - cfg_trx_no_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, femtobts_l1sapi_names, - "no gsmtap-sapi (", - "|",")", VTY_DO_LOWER); - cfg_trx_no_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, femtobts_l1sapi_names, - NO_STR "GSMTAP SAPI\n", - "\n", "", 0); - install_element_ve(&show_dsp_trace_f_cmd); install_element_ve(&show_sys_info_cmd); install_element_ve(&show_trx_clksrc_cmd); @@ -614,8 +536,6 @@ int bts_model_vty_init(struct gsm_bts *bts) install_element(TRX_NODE, &cfg_trx_clkcal_def_cmd); install_element(TRX_NODE, &cfg_trx_clksrc_cmd); install_element(TRX_NODE, &cfg_trx_cal_path_cmd); - install_element(TRX_NODE, &cfg_trx_gsmtap_sapi_cmd); - install_element(TRX_NODE, &cfg_trx_no_gsmtap_sapi_cmd); install_element(TRX_NODE, &cfg_trx_ul_power_target_cmd); install_element(TRX_NODE, &cfg_trx_min_qual_rach_cmd); install_element(TRX_NODE, &cfg_trx_min_qual_norm_cmd); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:50 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:50 +0200 Subject: [PATCH 31/33] Add gsmtap option to command line to main.c of osmo-bts-sysmo In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-32-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- src/osmo-bts-sysmo/main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 27b593b..8abff5f 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -47,6 +49,7 @@ #include #include #include +#include #define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock" @@ -64,6 +67,7 @@ static const char *config_file = "osmo-bts.cfg"; static int daemonize = 0; static unsigned int dsp_trace = 0x71c00020; static int rt_prio = -1; +static char *gsmtap_ip = 0; int bts_model_init(struct gsm_bts *bts) { @@ -167,6 +171,7 @@ static void print_help() " -w --hw-version Print the targeted HW Version\n" " -M --pcu-direct Force PCU to access message queue for " "PDCH dchannel directly\n" + " -i --gsmtap-ip The destination IP used for GSMTAP.\n" ); } @@ -198,10 +203,11 @@ static void handle_options(int argc, char **argv) { "hw-version", 0, 0, 'w' }, { "pcu-direct", 0, 0, 'M' }, { "realtime", 1, 0, 'r' }, + { "gsmtap-ip", 1, 0, 'i' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "hc:d:Dc:sTVe:p:w:Mr:", + c = getopt_long(argc, argv, "hc:d:Dc:sTVe:p:w:Mr:i:", long_options, &option_idx); if (c == -1) break; @@ -246,6 +252,9 @@ static void handle_options(int argc, char **argv) case 'r': rt_prio = atoi(optarg); break; + case 'i': + gsmtap_ip = optarg; + break; default: break; } @@ -328,6 +337,15 @@ int main(int argc, char **argv) } } + if (gsmtap_ip) { + gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1); + if (!gsmtap) { + fprintf(stderr, "Failed during gsmtap_init()\n"); + exit(1); + } + gsmtap_source_add_sink(gsmtap); + } + if (bts_init(bts) < 0) { fprintf(stderr, "unable to open bts\n"); exit(1); -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:51 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:51 +0200 Subject: [PATCH 32/33] Remove obsolete gsmtap handling from osmo-bts-sysmo part. In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-33-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- src/osmo-bts-sysmo/l1_if.c | 101 --------------------------------------------- src/osmo-bts-sysmo/l1_if.h | 3 -- 2 files changed, 104 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index b4ae300..2ba7c3c 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #include @@ -67,97 +65,6 @@ extern int pcu_direct; #define MIN_QUAL_RACH 5.0f /* at least 5 dB C/I */ #define MIN_QUAL_NORM -0.5f /* at least -1 dB C/I */ -/* mapping from femtobts L1 SAPI to GSMTAP channel type */ -static const uint8_t l1sapi2gsmtap_cht[GsmL1_Sapi_NUM] = { - [GsmL1_Sapi_Idle] = 255, - [GsmL1_Sapi_Fcch] = 255, - [GsmL1_Sapi_Sch] = 255, - [GsmL1_Sapi_Sacch] = GSMTAP_CHANNEL_SDCCH | GSMTAP_CHANNEL_ACCH, - [GsmL1_Sapi_Sdcch] = GSMTAP_CHANNEL_SDCCH, - [GsmL1_Sapi_Bcch] = GSMTAP_CHANNEL_BCCH, - [GsmL1_Sapi_Pch] = GSMTAP_CHANNEL_PCH, - [GsmL1_Sapi_Agch] = GSMTAP_CHANNEL_AGCH, - [GsmL1_Sapi_Cbch] = GSMTAP_CHANNEL_CBCH51, - [GsmL1_Sapi_Rach] = GSMTAP_CHANNEL_RACH, - [GsmL1_Sapi_TchF] = 255, - [GsmL1_Sapi_FacchF] = GSMTAP_CHANNEL_TCH_F, - [GsmL1_Sapi_TchH] = 255, - [GsmL1_Sapi_FacchH] = GSMTAP_CHANNEL_TCH_H, - [GsmL1_Sapi_Nch] = GSMTAP_CHANNEL_CCCH, - [GsmL1_Sapi_Pdtch] = GSMTAP_CHANNEL_PACCH, - [GsmL1_Sapi_Pacch] = GSMTAP_CHANNEL_PACCH, - [GsmL1_Sapi_Pbcch] = 255, - [GsmL1_Sapi_Pagch] = 255, - [GsmL1_Sapi_Ppch] = 255, - [GsmL1_Sapi_Pnch] = 255, - [GsmL1_Sapi_Ptcch] = GSMTAP_CHANNEL_PTCCH, - [GsmL1_Sapi_Prach] = 255, -}; - -static void tx_to_gsmtap(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - struct gsm_bts_trx *trx = fl1h->priv; - GsmL1_Prim_t *l1p = msgb_l1prim(msg); - GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq; - - if (fl1h->gsmtap) { - uint8_t ss, chan_type; - if (data_req->subCh == 0x1f) - ss = 0; - else - ss = data_req->subCh; - - if (!(fl1h->gsmtap_sapi_mask & (1 << data_req->sapi))) - return; - - chan_type = l1sapi2gsmtap_cht[data_req->sapi]; - if (chan_type == 255) - return; - - gsmtap_send(fl1h->gsmtap, trx->arfcn, data_req->u8Tn, - chan_type, ss, data_req->u32Fn, 0, 0, - data_req->msgUnitParam.u8Buffer, - data_req->msgUnitParam.u8Size); - } -} - -static void ul_to_gsmtap(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - struct gsm_bts_trx *trx = fl1h->priv; - GsmL1_Prim_t *l1p = msgb_l1prim(msg); - GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; - int skip = 0; - - if (fl1h->gsmtap) { - uint8_t ss, chan_type; - if (data_ind->subCh == 0x1f) - ss = 0; - else - ss = data_ind->subCh; - - if (!(fl1h->gsmtap_sapi_mask & (1 << data_ind->sapi))) - return; - - chan_type = l1sapi2gsmtap_cht[data_ind->sapi]; - if (chan_type == 255) - return; - if (chan_type == GSMTAP_CHANNEL_PACCH - || chan_type == GSMTAP_CHANNEL_PDCH) { - if (data_ind->msgUnitParam.u8Buffer[0] - != GsmL1_PdtchPlType_Full) - return; - skip = 1; - } - - gsmtap_send(fl1h->gsmtap, trx->arfcn | GSMTAP_ARFCN_F_UPLINK, - data_ind->u8Tn, chan_type, ss, data_ind->u32Fn, - data_ind->measParam.fRssi, - data_ind->measParam.fLinkQuality, - data_ind->msgUnitParam.u8Buffer + skip, - data_ind->msgUnitParam.u8Size - skip); - } -} - struct wait_l1_conf { struct llist_head list; /* internal linked list */ @@ -872,8 +779,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, } tx: - tx_to_gsmtap(fl1, resp_msg); - /* transmit */ osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], resp_msg); @@ -921,8 +826,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i uint8_t *data, len; int rc = 0; - ul_to_gsmtap(fl1, l1p_msg); - lchan = l1if_hLayer_to_lchan(fl1->priv, data_ind->hLayer2); if (!lchan) { LOGP(DL1C, LOGL_ERROR, @@ -1624,10 +1527,6 @@ struct femtol1_hdl *l1if_open(void *priv) return NULL; } - fl1h->gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 1); - if (fl1h->gsmtap) - gsmtap_source_add_sink(fl1h->gsmtap); - return fl1h; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index a425776..dba608c 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -53,9 +53,6 @@ struct femtol1_hdl { char *calib_path; struct llist_head wlc_list; - struct gsmtap_inst *gsmtap; - uint32_t gsmtap_sapi_mask; - void *priv; /* user reference */ struct osmo_timer_list alive_timer; -- 2.1.0 From laforge at gnumonks.org Wed Aug 27 21:54:52 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 27 Aug 2014 23:54:52 +0200 Subject: [PATCH 33/33] Move detection of handover frames from sysmo-bts code to common code In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <1409176492-13269-34-git-send-email-laforge@gnumonks.org> From: Andreas Eversberg --- src/common/l1sap.c | 4 ++++ src/osmo-bts-sysmo/l1_if.c | 13 ------------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index e006412..5318085 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -762,6 +762,10 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, return -EINVAL; } + /* report first valid received frame to handover process */ + if (lchan->ho.active == HANDOVER_WAIT_FRAME) + handover_frame(lchan); + if (L1SAP_IS_LINK_SACCH(link_id)) { radio_link_timeout(lchan, 0); le = &lchan->lapdm_ch.lapdm_acch; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 2ba7c3c..9707a22 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -819,22 +819,12 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i struct msgb *l1p_msg) { struct gsm_bts_trx *trx = fl1->priv; - struct gsm_lchan *lchan; uint8_t chan_nr, link_id; struct osmo_phsap_prim *l1sap; uint32_t fn; uint8_t *data, len; int rc = 0; - lchan = l1if_hLayer_to_lchan(fl1->priv, data_ind->hLayer2); - if (!lchan) { - LOGP(DL1C, LOGL_ERROR, - "unable to resolve lchan by hLayer2 for 0x%x\n", - data_ind->hLayer2); - msgb_free(l1p_msg); - return -ENODEV; - } - chan_nr = chan_nr_by_sapi(trx->ts[data_ind->u8Tn].pchan, data_ind->sapi, data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn); if (!chan_nr) { @@ -861,9 +851,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i data_ind->msgUnitParam.u8Size)); dump_meas_res(LOGL_DEBUG, &data_ind->measParam); - if (lchan->ho.active == HANDOVER_WAIT_FRAME) - handover_frame(lchan); - /* check for TCH */ if (data_ind->sapi == GsmL1_Sapi_TchF || data_ind->sapi == GsmL1_Sapi_TchH) { -- 2.1.0 From alexander.chemeris at gmail.com Thu Aug 28 01:11:06 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 27 Aug 2014 21:11:06 -0400 Subject: Final review of L1SAP ported to current maste In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: Harald, On Wed, Aug 27, 2014 at 5:54 PM, Harald Welte wrote: > the valuable L1SAP abstraction has been sitting out of master for too > long time. It is a pity that this has taken so long. I've finally been > able to put some time into osmo-bts again and reviewed the following > patch series. It consists of mostly Andreas' work, interspersed with > smaller patches/fixups that I introduced after the respective original > patch from Andreas. Great news! > I didn't yet rebase the osmo-bts-trx interface on top of the L1SAP, as I > don't have a hardware setup for it, and I will leave it to the owners of > such hardware to publish/push the respective code after L1SAP is merged. We'll look at that as soon as we have some free cycles. We would be happy to send you a free UmTRX to make sure you're able to work with the osmo-bts-trx part of the code. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. https://fairwaves.co From laforge at gnumonks.org Thu Aug 28 09:10:23 2014 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 28 Aug 2014 11:10:23 +0200 Subject: Final review of L1SAP ported to current maste In-Reply-To: References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <20140828091023.GT12087@nataraja> Hi Alexander, On Wed, Aug 27, 2014 at 09:11:06PM -0400, Alexander Chemeris wrote: > We would be happy to send you a free UmTRX to make sure you're able to > work with the osmo-bts-trx part of the code. Thanks for the offer, but I really do not have the time for this, sorry. I think it is fair that somebody who is a user / primary user of that platform/code is taking care of this. I don't mind if that person directly pushes code to master, as long as a) the code is not of general nature (which should go to src/common and be submitted for review) b) the code only makes modifications / additions to the src/osmo-bts-trx subdirectory 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 alexander.chemeris at gmail.com Fri Aug 29 02:26:53 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 28 Aug 2014 22:26:53 -0400 Subject: Final review of L1SAP ported to current maste In-Reply-To: <20140828091023.GT12087@nataraja> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <20140828091023.GT12087@nataraja> Message-ID: On Thu, Aug 28, 2014 at 5:10 AM, Harald Welte wrote: > On Wed, Aug 27, 2014 at 09:11:06PM -0400, Alexander Chemeris wrote: > I think it is fair that somebody who is a user / primary user of that > platform/code is taking care of this. I don't mind if that person > directly pushes code to master, as long as > a) the code is not of general nature (which should go to src/common and > be submitted for review) > b) the code only makes modifications / additions to the src/osmo-bts-trx > subdirectory Seems like a good approach to me. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. https://fairwaves.co From holger at freyther.de Thu Aug 28 11:52:25 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 28 Aug 2014 13:52:25 +0200 Subject: Final review of L1SAP ported to current maste In-Reply-To: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> Message-ID: <20140828115225.GA3508@xiaoyu.lan> > I have started a sysmobts between all of the major steps in this patch > series and did a short manual tests involving registration (LU) of two > MS, mobile-to-mobile call and vty-to-mobile SMS. So far I couldn't see > any problems. What has not been tested yet is the PCU interface as well > as encryption support. I plan to do this later this week. You can use the zecke/hacks/stress-testing branch in OpenBSC. It adds a VTY command to allocate all channels. It has found breakage in the past. From laforge at gnumonks.org Sat Aug 30 16:25:12 2014 From: laforge at gnumonks.org (Harald Welte) Date: Sat, 30 Aug 2014 18:25:12 +0200 Subject: Final review of L1SAP ported to current maste In-Reply-To: <20140828115225.GA3508@xiaoyu.lan> References: <1409176492-13269-1-git-send-email-laforge@gnumonks.org> <20140828115225.GA3508@xiaoyu.lan> Message-ID: <20140830162512.GR6653@nataraja> Hi Holger, On Thu, Aug 28, 2014 at 01:52:25PM +0200, Holger Hans Peter Freyther wrote: > > I have started a sysmobts between all of the major steps in this patch > > series and did a short manual tests involving registration (LU) of two > > MS, mobile-to-mobile call and vty-to-mobile SMS. So far I couldn't see > > any problems. What has not been tested yet is the PCU interface as well > > as encryption support. I plan to do this later this week. > > > You can use the zecke/hacks/stress-testing branch in OpenBSC. It adds > a VTY command to allocate all channels. It has found breakage in the > past. done that, the code survives multiple subsequent executions of 'allocate-all-channels' and shows no obvious memory leaks (neither in resident set size nor in the talloc report). -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From ciaby at autistici.org Sun Aug 31 20:07:58 2014 From: ciaby at autistici.org (Ciaby) Date: Sun, 31 Aug 2014 15:07:58 -0500 Subject: Can't build debian packages of libosmocore Message-ID: <5403809E.1090804@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 I'm having this problem with the latest code from git: root at boxie:~/gsm# git clone git://git.osmocom.org/libosmocore.git Cloning into 'libosmocore'... remote: Counting objects: 8770, done. remote: Compressing objects: 100% (4055/4055), done. remote: Total 8770 (delta 5642), reused 6765 (delta 4265) Receiving objects: 100% (8770/8770), 1.62 MiB | 142 KiB/s, done. Resolving deltas: 100% (5642/5642), done. root at boxie:~/gsm# cd libosmocore root at boxie:~/gsm/libosmocore# autoreconf -fi libtoolize: putting auxiliary files in `.'. libtoolize: copying file `./config.guess' libtoolize: copying file `./config.sub' libtoolize: copying file `./install-sh' libtoolize: copying file `./ltmain.sh' libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'. libtoolize: copying file `m4/libtool.m4' libtoolize: copying file `m4/ltoptions.m4' libtoolize: copying file `m4/ltsugar.m4' libtoolize: copying file `m4/ltversion.m4' libtoolize: copying file `m4/lt~obsolete.m4' configure.ac:5: installing `./missing' src/Makefile.am: installing `./depcomp' root at boxie:~/gsm/libosmocore# dpkg-buildpackage dpkg-buildpackage: export CFLAGS from dpkg-buildflags (origin: vendor): -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security dpkg-buildpackage: export CPPFLAGS from dpkg-buildflags (origin: vendor): -D_FORTIFY_SOURCE=2 dpkg-buildpackage: export CXXFLAGS from dpkg-buildflags (origin: vendor): -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security dpkg-buildpackage: export FFLAGS from dpkg-buildflags (origin: vendor): -g -O2 dpkg-buildpackage: export LDFLAGS from dpkg-buildflags (origin: vendor): -Wl,-Bsymbolic-functions -Wl,-z,relro dpkg-buildpackage: source package libosmocore dpkg-buildpackage: source version 0.7.0 dpkg-buildpackage: source changed by Harald Welte dpkg-buildpackage: host architecture amd64 dpkg-source --before-build libosmocore [...] make[1]: Entering directory `/home/rhizomatica/gsm/libosmocore' sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` dh_install dh_install: usr/lib/libosmogsm.so.5.1.0 exists in debian/tmp but is not installed to anywhere dh_install: usr/lib/libosmogsm.so.5 exists in debian/tmp but is not installed to anywhere dh_install: usr/lib/libosmoctrl.so.0.0.0 exists in debian/tmp but is not installed to anywhere dh_install: usr/lib/libosmoctrl.so.0 exists in debian/tmp but is not installed to anywhere dh_install: missing files, aborting make[1]: *** [override_dh_install] Error 2 make[1]: Leaving directory `/home/rhizomatica/gsm/libosmocore' make: *** [binary] Error 2 dpkg-buildpackage: error: debian/rules binary gave error exit status 2 So, it looks like it's trying to build a libosmogsm6 package, but only libosmogsm5.1.0 gets built. I looked around, and the only reference I found is in src/gsm/Makefile.am, and it's correct (6:0:1). What am I doing wrong? :) Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iF4EAREKAAYFAlQDgJkACgkQC30ZhxNccpF5EgD/TmeKcYFpr8O/XXA6RRS7zm10 boe6pxAd8XVku0bVdXsBAJ8zOiPhkTmXlrBc3Tdefrx+subagwnBV1RV4dbses4M =dqEo -----END PGP SIGNATURE----- From ciaby at autistici.org Sun Aug 31 21:02:17 2014 From: ciaby at autistici.org (Ciaby) Date: Sun, 31 Aug 2014 16:02:17 -0500 Subject: Can't build debian packages of libosmocore In-Reply-To: <5403809E.1090804@autistici.org> References: <5403809E.1090804@autistici.org> Message-ID: <54038D59.7080407@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 08/31/2014 03:07 PM, Ciaby wrote: > I'm having this problem with the latest code from git: [...] > So, it looks like it's trying to build a libosmogsm6 package, but > only libosmogsm5.1.0 gets built. I looked around, and the only > reference I found is in src/gsm/Makefile.am, and it's correct > (6:0:1). What am I doing wrong? :) This is a tentative patch to fix the issue. It works for me, libosmogsm6 and libosmoctrl0 are built successfully, however I'm not sure if that's the right thing to do. Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iF4EAREKAAYFAlQDjVAACgkQC30ZhxNccpEJNAD/Z5uiLUwGkKfEfl331bOk7yRo 1rG1g1qDJsz7InEEzZwA/RC24KagL8xZDSNtRjl6i+mU97XqoL+BoFsvqV2M6c/2 =o+xL -----END PGP SIGNATURE----- From ciaby at rhizomatica.org Sun Aug 31 20:35:29 2014 From: ciaby at rhizomatica.org (Ciaby) Date: Sun, 31 Aug 2014 15:35:29 -0500 Subject: [PATCH] debian: fix build errors with libosmogsm and libosmoctrl Message-ID: libosmogsm: the transition from 5 to 6 wasn't done properly. Fixed version number. libosmoctrl: missing definition in debian/control and also missing libosmoctrl0.install. --- debian/control | 6 ++++++ debian/libosmoctrl0.install | 1 + debian/libosmogsm5.install | 1 - debian/libosmogsm6.install | 1 + src/gsm/Makefile.am | 2 +- 5 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 debian/libosmoctrl0.install delete mode 100644 debian/libosmogsm5.install create mode 100644 debian/libosmogsm6.install diff --git a/debian/control b/debian/control index 3204f0f..e81f7cf 100644 --- a/debian/control +++ b/debian/control @@ -44,6 +44,12 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Osmo VTY library +Package: libosmoctrl0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Osmo control library + Package: libosmocore-dev Section: libdevel Architecture: any diff --git a/debian/libosmoctrl0.install b/debian/libosmoctrl0.install new file mode 100644 index 0000000..6b23be8 --- /dev/null +++ b/debian/libosmoctrl0.install @@ -0,0 +1 @@ +usr/lib/libosmoctrl*.so.* diff --git a/debian/libosmogsm5.install b/debian/libosmogsm5.install deleted file mode 100644 index 12c9180..0000000 --- a/debian/libosmogsm5.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/libosmogsm*.so.* diff --git a/debian/libosmogsm6.install b/debian/libosmogsm6.install new file mode 100644 index 0000000..12c9180 --- /dev/null +++ b/debian/libosmogsm6.install @@ -0,0 +1 @@ +usr/lib/libosmogsm*.so.* diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 4207959..1e2d893 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -1,6 +1,6 @@ # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification -LIBVERSION=6:0:1 +LIBVERSION=6:0:0 AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN} $(all_includes) -I$(top_srcdir)/include -- 1.7.9.5 --------------020605080303040703010001 Content-Type: application/octet-stream; name="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.patch.sig" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.pa"; filename*1="tch.sig" iF4EABEKAAYFAlQDjVQACgkQC30ZhxNccpEcUwD+PuSik47JmvVhLd7L74WaPo70JqqsK1MN zN8pgoPwYhEBAJXssWBprtwVxVGNVd0dcS7eEBQMF5By6ksG436tapcS --------------020605080303040703010001-- From ciaby at rhizomatica.org Sun Aug 31 20:35:29 2014 From: ciaby at rhizomatica.org (Ciaby) Date: Sun, 31 Aug 2014 15:35:29 -0500 Subject: [PATCH] debian: fix build errors with libosmogsm and libosmoctrl Message-ID: libosmogsm: the transition from 5 to 6 wasn't done properly. Fixed version number. libosmoctrl: missing definition in debian/control and also missing libosmoctrl0.install. --- debian/control | 6 ++++++ debian/libosmoctrl0.install | 1 + debian/libosmogsm5.install | 1 - debian/libosmogsm6.install | 1 + src/gsm/Makefile.am | 2 +- 5 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 debian/libosmoctrl0.install delete mode 100644 debian/libosmogsm5.install create mode 100644 debian/libosmogsm6.install diff --git a/debian/control b/debian/control index 3204f0f..e81f7cf 100644 --- a/debian/control +++ b/debian/control @@ -44,6 +44,12 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Osmo VTY library +Package: libosmoctrl0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Osmo control library + Package: libosmocore-dev Section: libdevel Architecture: any diff --git a/debian/libosmoctrl0.install b/debian/libosmoctrl0.install new file mode 100644 index 0000000..6b23be8 --- /dev/null +++ b/debian/libosmoctrl0.install @@ -0,0 +1 @@ +usr/lib/libosmoctrl*.so.* diff --git a/debian/libosmogsm5.install b/debian/libosmogsm5.install deleted file mode 100644 index 12c9180..0000000 --- a/debian/libosmogsm5.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/libosmogsm*.so.* diff --git a/debian/libosmogsm6.install b/debian/libosmogsm6.install new file mode 100644 index 0000000..12c9180 --- /dev/null +++ b/debian/libosmogsm6.install @@ -0,0 +1 @@ +usr/lib/libosmogsm*.so.* diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 4207959..1e2d893 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -1,6 +1,6 @@ # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification -LIBVERSION=6:0:1 +LIBVERSION=6:0:0 AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN} $(all_includes) -I$(top_srcdir)/include -- 1.7.9.5 --------------070700020400040502040808 Content-Type: application/octet-stream; name="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.patch.sig" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.pa"; filename*1="tch.sig" iF4EABEKAAYFAlQGAmEACgkQC30ZhxNccpHMZAEAuXAMQd3yavDff+y8bU0ZEWKORaplPlFS iEZ706MhotYA/ioKSXn35kmFyDFIv7Kdzcf5GmVDdwS8OwhCBJrJWv83 --------------070700020400040502040808-- From ciaby at rhizomatica.org Sun Aug 31 20:35:29 2014 From: ciaby at rhizomatica.org (Ciaby) Date: Sun, 31 Aug 2014 15:35:29 -0500 Subject: [PATCH] debian: fix build errors with libosmogsm and libosmoctrl Message-ID: libosmogsm: the transition from 5 to 6 wasn't done properly. Fixed version number. libosmoctrl: missing definition in debian/control and also missing libosmoctrl0.install. --- debian/control | 6 ++++++ debian/libosmoctrl0.install | 1 + .../{libosmogsm5.install => libosmogsm6.install} | 0 src/gsm/Makefile.am | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 debian/libosmoctrl0.install rename debian/{libosmogsm5.install => libosmogsm6.install} (100%) diff --git a/debian/control b/debian/control index 3204f0f..e81f7cf 100644 --- a/debian/control +++ b/debian/control @@ -44,6 +44,12 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Osmo VTY library +Package: libosmoctrl0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Osmo control library + Package: libosmocore-dev Section: libdevel Architecture: any diff --git a/debian/libosmoctrl0.install b/debian/libosmoctrl0.install new file mode 100644 index 0000000..6b23be8 --- /dev/null +++ b/debian/libosmoctrl0.install @@ -0,0 +1 @@ +usr/lib/libosmoctrl*.so.* diff --git a/debian/libosmogsm5.install b/debian/libosmogsm6.install similarity index 100% rename from debian/libosmogsm5.install rename to debian/libosmogsm6.install diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 4207959..1e2d893 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -1,6 +1,6 @@ # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification -LIBVERSION=6:0:1 +LIBVERSION=6:0:0 AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN} $(all_includes) -I$(top_srcdir)/include -- 1.7.9.5 --------------080008040908010200020003 Content-Type: application/octet-stream; name="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.patch.sig" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0="0001-debian-fix-build-errors-with-libosmogsm-and-libosmoc.pa"; filename*1="tch.sig" iF4EABEKAAYFAlQGBL8ACgkQC30ZhxNccpFrWQD/ZM1qKhGG0XYqxdU6adl3sub3NOTZk6XE DeprqaFLzGgA/R0FmlHzefNHPxRgZo0NnUNVamw65cfmhB1jGbnMMjH2 --------------080008040908010200020003--