From alexander.chemeris at gmail.com Sun Mar 9 11:39:08 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 12:39:08 +0100 Subject: [PATCH] sms_queue,smpp: Refactor MO SUBMIT code to make further changes easier. In-Reply-To: <1380970848-12958-1-git-send-email-Alexander.Chemeris@gmail.com> References: <1380970848-12958-1-git-send-email-Alexander.Chemeris@gmail.com> Message-ID: Following up with yesterday's discussion about SMS routing, I would like to re-submit this patch. On Sat, Oct 5, 2013 at 1:00 PM, Alexander Chemeris wrote: > This is required to implement normal prefix/regexp routing in addition to > the current "if unroutable" model. > --- > openbsc/src/libmsc/gsm_04_11.c | 63 +++++++++++++++++++++++----------------- > 1 file changed, 37 insertions(+), 26 deletions(-) > > diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c > index e554b74..7e8ede8 100644 > --- a/openbsc/src/libmsc/gsm_04_11.c > +++ b/openbsc/src/libmsc/gsm_04_11.c > @@ -279,6 +279,39 @@ static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms) > return msg->len - old_msg_len; > } > > +static int sms_queue_try_deliver(struct gsm_subscriber_connection *conn, > + struct msgb *msg, struct gsm_sms *gsms) > +{ > + /* determine gsms->receiver based on dialled number */ > + gsms->receiver = subscr_get_by_extension(conn->bts->network, gsms->dst.addr); > + if (!gsms->receiver) { > + rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; > + goto out; > + } > + > + switch (sms_mti) { > + case GSM340_SMS_SUBMIT_MS2SC: > + /* MS is submitting a SMS */ > + rc = gsm340_rx_sms_submit(msg, gsms); > + break; > + case GSM340_SMS_COMMAND_MS2SC: > + case GSM340_SMS_DELIVER_REP_MS2SC: > + LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti); > + rc = GSM411_RP_CAUSE_IE_NOTEXIST; > + break; > + default: > + LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti); > + rc = GSM411_RP_CAUSE_IE_NOTEXIST; > + break; > + } > + > + if (!rc && !gsms->receiver) > + rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; > + > +out: > + return rc; > +} > + > /* process an incoming TPDU (called from RP-DATA) > * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */ > static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *msg) > @@ -393,44 +426,22 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m > /* FIXME: This looks very wrong */ > send_signal(0, NULL, gsms, 0); > > - /* determine gsms->receiver based on dialled number */ > - gsms->receiver = subscr_get_by_extension(conn->bts->network, gsms->dst.addr); > - if (!gsms->receiver) { > + rc = sms_queue_try_deliver(conn, msg, gsms); > + if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) { > #ifdef BUILD_SMPP > rc = smpp_try_deliver(gsms, conn); > - if (rc == 1) { > - rc = 1; /* cause 1: unknown subscriber */ > + if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) { > osmo_counter_inc(conn->bts->network->stats.sms.no_receiver); > } else if (rc < 0) { > - rc = 21; /* cause 21: short message transfer rejected */ > + rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; > /* FIXME: handle the error somehow? */ > } > #else > - rc = 1; /* cause 1: unknown subscriber */ > osmo_counter_inc(conn->bts->network->stats.sms.no_receiver); > #endif > goto out; > } > > - switch (sms_mti) { > - case GSM340_SMS_SUBMIT_MS2SC: > - /* MS is submitting a SMS */ > - rc = gsm340_rx_sms_submit(msg, gsms); > - break; > - case GSM340_SMS_COMMAND_MS2SC: > - case GSM340_SMS_DELIVER_REP_MS2SC: > - LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti); > - rc = GSM411_RP_CAUSE_IE_NOTEXIST; > - break; > - default: > - LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti); > - rc = GSM411_RP_CAUSE_IE_NOTEXIST; > - break; > - } > - > - if (!rc && !gsms->receiver) > - rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; > - > out: > sms_free(gsms); > > -- > 1.7.9.5 > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From Max.Suraev at fairwaves.ru Fri Mar 7 16:37:19 2014 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Fri, 07 Mar 2014 17:37:19 +0100 Subject: Fwd: Re: [PATCH] Use generic osmocom auth api In-Reply-To: <52BDF900.9020901@fairwaves.ru> References: <52BDF900.9020901@fairwaves.ru> Message-ID: <5319F5BF.7060303@fairwaves.ru> Hi. As a follow-up for recent discussion - here is the patch from CCC. -------- ???????? ????????? -------- ????: Re: [PATCH] Use generic osmocom auth api ????: Fri, 27 Dec 2013 23:02:40 +0100 ??: ? ????: openbsc at lists.osmocom.org Here it is - rely on libosmocore to do the right stuff for us. -- best regards, Max, http://fairwaves.ru From holger at freyther.de Sun Mar 9 16:22:21 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 17:22:21 +0100 Subject: [PATCH 2/9] Use helper function to check if an MNCC frame is data (speech/traffic) In-Reply-To: <1392793078-30854-2-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-2-git-send-email-jolly@eversberg.eu> Message-ID: <20140309162221.GE6167@xiaoyu.lan> On Wed, Feb 19, 2014 at 07:57:51AM +0100, Andreas Eversberg wrote: > +#define mncc_is_data_frame(msg_type) \ Would calling this mncc_is_audio_frame make sense? holger From andreas at eversberg.eu Mon Mar 10 08:17:13 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 10 Mar 2014 09:17:13 +0100 Subject: [PATCH 2/9] Use helper function to check if an MNCC frame is data (speech/traffic) In-Reply-To: <20140309162221.GE6167@xiaoyu.lan> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-2-git-send-email-jolly@eversberg.eu> <20140309162221.GE6167@xiaoyu.lan> Message-ID: <531D7509.7010006@eversberg.eu> Holger Hans Peter Freyther wrote: >> +#define mncc_is_data_frame(msg_type) \ > Would calling this mncc_is_audio_frame make sense? > > holger i thought about it. the reason i call it "data_frame" is because it would also apply to CSD frames that are not (yet) supported. From holger at freyther.de Thu Mar 20 21:46:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 22:46:03 +0100 Subject: [PATCH 4/9] Add support for AMR frames to MNCC/RTP interface In-Reply-To: <1392793078-30854-4-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-4-git-send-email-jolly@eversberg.eu> Message-ID: <20140320214603.GA11963@xiaoyu.lan> On Wed, Feb 19, 2014 at 07:57:53AM +0100, Andreas Eversberg wrote: The patch does not do what the subject is saying. This implements the AMR frame handling. It is a bit unfortunate that NITB is now announcing version4 and not all new features are implemented yet. This somehow defeats the purpose of versioning the protocol. I don't know if you remember but I added the version number as I was trying to figure out why NITB/LCR didn't work together... > + int is_amr = 0; by your choice of name you indicate this is a boolean. > + if (is_amr) > + frame->data[0] = payload_len; > + memcpy(frame->data + is_amr, payload, payload_len); > + msgb_put(new_msg, sizeof(struct gsm_data_frame) + is_amr + payload_len); here you use it like an int/offset. What about using the msgg routines from the tlv.h code to append the value and data? > + int is_amr = 0; same > + memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + is_amr, > + payload_len); same issue here with boolean. From holger at freyther.de Sun Mar 9 16:19:52 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 17:19:52 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <1392793078-30854-6-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> Message-ID: <20140309161952.GC6167@xiaoyu.lan> On Wed, Feb 19, 2014 at 07:57:55AM +0100, Andreas Eversberg wrote: Dear Andreas, Harald, the osmo-bsc_nat would require a dummy tch_frame_down implementation. The NAT is using libbsc for bsc_msc.c and gsm48_create_mm_serv_rej, gsm48_create_loc_upd_rej, gsm48_extract_mi, gsm48_paging_extract_mi and gsm_net_update_ctype. Currently libbsc depends on libtrau. Can we move the rtp_socket to another library? Or move out the code used by nat to another libbsc? What do you think? holger > +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data); > +/* dummy function to keep rtp_proxy.c happy */ > +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) > +{ > + return 0; > +} > +/* dummy function to keep rtp_proxy.c happy */ > +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) > +{ > + return 0; > +} > +/* dummy function to keep rtp_proxy.c happy */ > +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) > +{ > + return 0; > +} > + > --- a/openbsc/tests/gbproxy/gbproxy_test.c > +++ b/openbsc/tests/gbproxy/gbproxy_test.c > @@ -34,6 +34,12 @@ > > #define SGSN_NSEI 0x0100 > > +/* dummy function to keep rtp_proxy.c happy */ > +int tch_frame_down() > +{ > + return 0; > +} > + From andreas at eversberg.eu Tue Mar 11 06:29:01 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 11 Mar 2014 07:29:01 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <20140309161952.GC6167@xiaoyu.lan> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> Message-ID: <531EAD2D.6000702@eversberg.eu> Holger Hans Peter Freyther wrote: > Currently libbsc depends on libtrau. Can we move the rtp_socket to > another library? Or move out the code used by nat to another libbsc? > > What do you think? > holger > >> >+int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data); dear holger, dear harald, i think it would make sense to move tch_frame_down() to rtp_proxy.c. at least we could get rid of all the dummy implementations for this function. best regards, andreas From holger at freyther.de Fri Mar 14 06:40:42 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 14 Mar 2014 07:40:42 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <531EAD2D.6000702@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> <531EAD2D.6000702@eversberg.eu> Message-ID: <20140314064042.GJ31238@xiaoyu.lan> On Tue, Mar 11, 2014 at 07:29:01AM +0100, Andreas Eversberg wrote: > i think it would make sense to move tch_frame_down() to rtp_proxy.c. > at least we could get rid of all the dummy implementations for this > function. Good Morning, could you attempt to make a patch like this? The goal is to have the NAT code link without modifications. But we can solve this by spliting out GSM 04.08 message generating/parsing from libbsc as well. holger From andreas at eversberg.eu Sat Mar 15 09:41:38 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 15 Mar 2014 10:41:38 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <20140314064042.GJ31238@xiaoyu.lan> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> <531EAD2D.6000702@eversberg.eu> <20140314064042.GJ31238@xiaoyu.lan> Message-ID: <53242052.1070401@eversberg.eu> Holger Hans Peter Freyther wrote: > On Tue, Mar 11, 2014 at 07:29:01AM +0100, Andreas Eversberg wrote: > >> i think it would make sense to move tch_frame_down() to rtp_proxy.c. >> at least we could get rid of all the dummy implementations for this >> function. > Good Morning, > > could you attempt to make a patch like this? The goal is to have the > NAT code link without modifications. But we can solve this by spliting > out GSM 04.08 message generating/parsing from libbsc as well. > > holger dear holger, i tried to move the tch_frame_down() to trau_mux.c. this function requires trans_find_by_callref(), which is part of libmsc. now all programs that link libtrau will also need to be linked to libmsc. best regards, andreas From holger at freyther.de Sun Mar 16 07:12:40 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 16 Mar 2014 08:12:40 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <53242052.1070401@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> <531EAD2D.6000702@eversberg.eu> <20140314064042.GJ31238@xiaoyu.lan> <53242052.1070401@eversberg.eu> Message-ID: <20140316071240.GD27189@xiaoyu.lan> On Sat, Mar 15, 2014 at 10:41:38AM +0100, Andreas Eversberg wrote: hi, > i tried to move the tch_frame_down() to trau_mux.c. this function > requires trans_find_by_callref(), which is part of libmsc. now all > programs that link libtrau will also need to be linked to libmsc. libbsc requires libtrau, libtrau requires libmsc. So the OsmoBSC and the OsmoNAT would now require libmsc. That is an even bigger step backward. :( Can you move the rtp_socket from the libbsc to the libmsc and use the SS_ABISIP signals just like src/osmo-bsc/osmo_bsc_audio.c is doing it? thanks holger From andreas at eversberg.eu Mon Mar 17 06:42:08 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 17 Mar 2014 07:42:08 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <20140316071240.GD27189@xiaoyu.lan> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> <531EAD2D.6000702@eversberg.eu> <20140314064042.GJ31238@xiaoyu.lan> <53242052.1070401@eversberg.eu> <20140316071240.GD27189@xiaoyu.lan> Message-ID: <53269940.7050101@eversberg.eu> Holger Hans Peter Freyther wrote: > Can you move the rtp_socket from the libbsc to the libmsc and use > the SS_ABISIP signals just like src/osmo-bsc/osmo_bsc_audio.c is > doing it? sorry, but i don't understand what you mean by moving the rtp_socket. also, what can i use the SS_ABISIP signal for? From holger at freyther.de Thu Mar 20 21:49:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 22:49:38 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <53269940.7050101@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-6-git-send-email-jolly@eversberg.eu> <20140309161952.GC6167@xiaoyu.lan> <531EAD2D.6000702@eversberg.eu> <20140314064042.GJ31238@xiaoyu.lan> <53242052.1070401@eversberg.eu> <20140316071240.GD27189@xiaoyu.lan> <53269940.7050101@eversberg.eu> Message-ID: <20140320214938.GB11963@xiaoyu.lan> On Mon, Mar 17, 2014 at 07:42:08AM +0100, Andreas Eversberg wrote: > Holger Hans Peter Freyther wrote: > >Can you move the rtp_socket from the libbsc to the libmsc and use > >the SS_ABISIP signals just like src/osmo-bsc/osmo_bsc_audio.c is > >doing it? > sorry, but i don't understand what you mean by moving the > rtp_socket. also, what can i use the SS_ABISIP signal for? Do you understand why the bsc can't use/link libmsc and that circular lib depedencies are an issue? I proposed/asked if you could move the rtp_socket into libmsc? The code in src/osmo-bsc/osmo_bsc_audio.c is solving a similar problem that NITB is dealing with rtp_socket.c. So you could introduce a loose coupling here.. through the signal framework. is that more clear? I currently can't merge this patch as it breaks the NAT compilation. holger From holger at freyther.de Sun Mar 9 16:21:17 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 17:21:17 +0100 Subject: [PATCH 1/9] Complete definitions for all speech traffic frames at MNCC interface In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <20140309162117.GD6167@xiaoyu.lan> On Wed, Feb 19, 2014 at 07:57:50AM +0100, Andreas Eversberg wrote: > The new definitions are: half rate and AMR > > Change of definition name for bad frame, because it applies to all types of > traffic, not only TCH/F. > > Increase MNCC interface version to 4. > -#define MNCC_SOCK_VERSION 2 > +#define MNCC_SOCK_VERSION 4 Has version 3 three been used somewhere else? From andreas at eversberg.eu Mon Mar 10 08:13:30 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 10 Mar 2014 09:13:30 +0100 Subject: [PATCH 1/9] Complete definitions for all speech traffic frames at MNCC interface In-Reply-To: <20140309162117.GD6167@xiaoyu.lan> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <20140309162117.GD6167@xiaoyu.lan> Message-ID: <531D742A.8020402@eversberg.eu> Holger Hans Peter Freyther wrote: >> -#define MNCC_SOCK_VERSION 2 >> +#define MNCC_SOCK_VERSION 4 > Has version 3 three been used somewhere else? dear holger, yes, it was used before i rebased my testing branch. the former version 3 had more features and was incompatible with this version 4. best regards, andreas From holger at freyther.de Tue Mar 11 14:18:13 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Mar 2014 15:18:13 +0100 Subject: [PATCH 1/9] Complete definitions for all speech traffic frames at MNCC interface In-Reply-To: <531D742A.8020402@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <20140309162117.GD6167@xiaoyu.lan> <531D742A.8020402@eversberg.eu> Message-ID: <20140311141813.GG17965@xiaoyu.lan> On Mon, Mar 10, 2014 at 09:13:30AM +0100, Andreas Eversberg wrote: > yes, it was used before i rebased my testing branch. the former > version 3 had more features and was incompatible with this version > 4. This is important information that should be in the commit message. Is the LCR branch that implemented version 3 of the protocol available to the public? How likely is it that somebody will end up using it? holger From jerlbeck at sysmocom.de Mon Mar 3 09:44:28 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 3 Mar 2014 10:44:28 +0100 Subject: [PATCH] agch/test: Add test for AGCH queue handling In-Reply-To: <1393025770-14352-4-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-4-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393839868-1359-1-git-send-email-jerlbeck@sysmocom.de> The first test checks the AGCH may queue length computation. The second test fills the queue by calling bts_agch_enqueue() with a mix of IMM.ASS and IMM.ASS.REJ. Then it drains the queue by calling bts_ccch_copy_msg(). After each of both steps, statistics are printed out. Sponsored-by: On-Waves ehf --- configure.ac | 1 + tests/Makefile.am | 2 +- tests/agch/Makefile.am | 8 ++ tests/agch/agch_test.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++ tests/agch/agch_test.ok | 23 +++++ tests/testsuite.at | 6 ++ 6 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 tests/agch/Makefile.am create mode 100644 tests/agch/agch_test.c create mode 100644 tests/agch/agch_test.ok diff --git a/configure.ac b/configure.ac index 3411017..ff46b5a 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,7 @@ AC_OUTPUT( include/osmo-bts/Makefile tests/Makefile tests/paging/Makefile + tests/agch/Makefile tests/cipher/Makefile tests/sysmobts/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 5fb128f..b32241b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher sysmobts +SUBDIRS = paging cipher sysmobts agch # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/agch/Makefile.am b/tests/agch/Makefile.am new file mode 100644 index 0000000..a0c5eed --- /dev/null +++ b/tests/agch/Makefile.am @@ -0,0 +1,8 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -lortp +noinst_PROGRAMS = agch_test +EXTRA_DIST = agch_test.ok + +agch_test_SOURCES = agch_test.c $(srcdir)/../stubs.c +agch_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/agch/agch_test.c b/tests/agch/agch_test.c new file mode 100644 index 0000000..5f4aa01 --- /dev/null +++ b/tests/agch/agch_test.c @@ -0,0 +1,251 @@ +/* testing the agch code */ + +/* (C) 2011 by Holger Hans Peter Freyther + * (C) 2014 by Sysmocom sfmc GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +static struct gsm_bts *bts; +static struct gsm_bts_role_bts *btsb; +int pcu_direct = 0; + +static const uint8_t static_ilv[] = { + 0x08, 0x59, 0x51, 0x30, 0x99, 0x00, 0x00, 0x00, 0x19 +}; + +#define ASSERT_TRUE(rc) \ + if (!(rc)) { \ + printf("Assert failed in %s:%d.\n", \ + __FILE__, __LINE__); \ + abort(); \ + } + +static int count_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej) +{ + int count = 0; + count++; + + if (memcmp(&rej->req_ref1, &rej->req_ref2, sizeof(rej->req_ref2))) { + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref3, sizeof(rej->req_ref3)) + && memcmp(&rej->req_ref2, &rej->req_ref3, sizeof(rej->req_ref3))) { + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref2, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref3, &rej->req_ref4, sizeof(rej->req_ref4))) { + count++; + } + + return count; +} + +static void put_imm_ass_rej(struct msgb *msg, int idx, uint8_t wait_ind) +{ + /* GSM CCCH - Immediate Assignment Reject */ + static const unsigned char gsm_a_ccch_data[23] = { + 0x4d, 0x06, 0x3a, 0x03, 0x25, 0x00, 0x00, 0x0a, + 0x25, 0x00, 0x00, 0x0a, 0x25, 0x00, 0x00, 0x0a, + 0x25, 0x00, 0x00, 0x0a, 0x2b, 0x2b, 0x2b + }; + + struct gsm48_imm_ass_rej *rej; + msg->l3h = msgb_put(msg, sizeof(gsm_a_ccch_data)); + rej = (struct gsm48_imm_ass_rej *)msg->l3h; + memmove(msg->l3h, gsm_a_ccch_data, sizeof(gsm_a_ccch_data)); + + rej->req_ref1.t1 = idx; + rej->wait_ind1 = wait_ind; + + rej->req_ref2.t1 = idx; + rej->req_ref3.t1 = idx; + rej->req_ref4.t1 = idx; +} + +static void put_imm_ass(struct msgb *msg, int idx) +{ + /* GSM CCCH - Immediate Assignment */ + static const unsigned char gsm_a_ccch_data[23] = { + 0x2d, 0x06, 0x3f, 0x03, 0x0c, 0xe3, 0x69, 0x25, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b + }; + + struct gsm48_imm_ass *ima; + msg->l3h = msgb_put(msg, sizeof(gsm_a_ccch_data)); + ima = (struct gsm48_imm_ass *)msg->l3h; + memmove(msg->l3h, gsm_a_ccch_data, sizeof(gsm_a_ccch_data)); + + ima->req_ref.t1 = idx; +} + +static void test_agch_queue(void) +{ + int rc; + uint8_t out_buf[GSM_MACBLOCK_LEN]; + struct gsm_time g_time; + const int num_rounds = 40; + const int num_ima_per_round = 2; + const int num_rej_per_round = 16; + + int round, idx; + int count = 0; + struct msgb *msg = NULL; + int multiframes = 0; + int imm_ass_count = 0; + int imm_ass_rej_count = 0; + int imm_ass_rej_ref_count = 0; + + g_time.fn = 0; + g_time.t1 = 0; + g_time.t2 = 0; + g_time.t3 = 6; + + printf("Testing AGCH messages queue handling.\n"); + btsb->agch_max_queue_length = 32; + + for (round = 1; round <= num_rounds; round++) { + for (idx = 0; idx < num_ima_per_round; idx++) { + msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + put_imm_ass(msg, ++count); + bts_agch_enqueue(bts, msg); + imm_ass_count++; + } + for (idx = 0; idx < num_rej_per_round; idx++) { + msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + put_imm_ass_rej(msg, ++count, 10); + bts_agch_enqueue(bts, msg); + imm_ass_rej_count++; + imm_ass_rej_ref_count++; + } + } + + printf("AGCH filled: count %u, imm.ass %d, imm.ass.rej %d (refs %d), " + "queue limit %u, occupied %d, " + "dropped %llu, merged %llu, rejected %llu, " + "ag-res %llu, non-res %llu\n", + count, imm_ass_count, imm_ass_rej_count, imm_ass_rej_ref_count, + btsb->agch_max_queue_length, btsb->agch_queue_length, + btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, + btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, + btsb->agch_queue_pch_msgs); + + imm_ass_count = 0; + imm_ass_rej_count = 0; + imm_ass_rej_ref_count = 0; + + for (idx = 0; 1; idx++) { + struct gsm48_imm_ass *ima; + int is_agch = (idx % 3) == 0; /* 1 AG reserved, 2 PCH */ + if (is_agch) + multiframes++; + + rc = bts_ccch_copy_msg(bts, out_buf, &g_time, is_agch); + ima = (struct gsm48_imm_ass *)out_buf; + switch (ima->msg_type) { + case GSM48_MT_RR_IMM_ASS: + imm_ass_count++; + break; + case GSM48_MT_RR_IMM_ASS_REJ: + imm_ass_rej_count++; + imm_ass_rej_ref_count += + count_imm_ass_rej_refs((struct gsm48_imm_ass_rej *)ima); + break; + default: + break; + } + if (is_agch && rc <= 0) + break; + + } + + printf("AGCH drained: multiframes %u, imm.ass %d, imm.ass.rej %d (refs %d), " + "queue limit %u, occupied %d, " + "dropped %llu, merged %llu, rejected %llu, " + "ag-res %llu, non-res %llu\n", + multiframes, imm_ass_count, imm_ass_rej_count, imm_ass_rej_ref_count, + btsb->agch_max_queue_length, btsb->agch_queue_length, + btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, + btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, + btsb->agch_queue_pch_msgs); +} + +static void test_agch_queue_length_computation(void) +{ + static const int ccch_configs[] = { + RSL_BCCH_CCCH_CONF_1_NC, + RSL_BCCH_CCCH_CONF_1_C, + RSL_BCCH_CCCH_CONF_2_NC, + RSL_BCCH_CCCH_CONF_3_NC, + RSL_BCCH_CCCH_CONF_4_NC, + }; + static const uint8_t tx_integer[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50, + }; + + int T_idx, c_idx, max_len; + + printf("Testing AGCH queue length computation.\n"); + + printf("T\t\tBCCH slots\n"); + printf("\t1(NC)\t1(C)\t2(NC)\t3(NC)\t4(NC)\n"); + for (T_idx = 0; T_idx < ARRAY_SIZE(tx_integer); T_idx++) { + printf("%d", tx_integer[T_idx]); + for (c_idx = 0; c_idx < ARRAY_SIZE(ccch_configs); c_idx++) { + max_len = bts_agch_max_queue_length(tx_integer[T_idx], + ccch_configs[c_idx]); + printf("\t%d", max_len); + } + printf("\n"); + } +} + +int main(int argc, char **argv) +{ + void *tall_msgb_ctx; + + tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); + tall_msgb_ctx = talloc_named_const(tall_bts_ctx, 1, "msgb"); + msgb_set_talloc_ctx(tall_msgb_ctx); + + bts_log_init(NULL); + + bts = gsm_bts_alloc(tall_bts_ctx); + if (bts_init(bts) < 0) { + fprintf(stderr, "unable to open bts\n"); + exit(1); + } + + btsb = bts_role_bts(bts); + test_agch_queue_length_computation(); + test_agch_queue(); + printf("Success\n"); + + return 0; +} + diff --git a/tests/agch/agch_test.ok b/tests/agch/agch_test.ok new file mode 100644 index 0000000..e8d29bf --- /dev/null +++ b/tests/agch/agch_test.ok @@ -0,0 +1,23 @@ +Testing AGCH queue length computation. +T BCCH slots + 1(NC) 1(C) 2(NC) 3(NC) 4(NC) +3 20 9 20 20 20 +4 28 11 28 28 28 +5 40 13 40 40 40 +6 59 19 59 59 59 +7 79 25 79 79 79 +8 21 9 21 21 21 +9 28 12 28 28 28 +10 40 13 40 40 40 +11 60 20 60 60 60 +12 80 26 80 80 80 +14 22 10 22 22 22 +16 30 13 30 30 30 +20 42 14 42 42 42 +25 63 21 63 63 63 +32 83 28 83 83 83 +50 28 14 28 28 28 +Testing AGCH messages queue handling. +AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 720, dropped 0, merged 0, rejected 0, ag-res 0, non-res 0 +AGCH drained: multiframes 721, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 0, dropped 0, merged 0, rejected 0, ag-res 720, non-res 0 +Success diff --git a/tests/testsuite.at b/tests/testsuite.at index 1297421..ec3021f 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -7,6 +7,12 @@ cat $abs_srcdir/paging/paging_test.ok > expout AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/paging/paging_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([agch]) +AT_KEYWORDS([agch]) +cat $abs_srcdir/agch/agch_test.ok > expout +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/agch/agch_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([cipher]) AT_KEYWORDS([cipher]) cat $abs_srcdir/cipher/cipher_test.ok > expout -- 1.7.9.5 From holger at freyther.de Sun Mar 2 08:09:33 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 2 Mar 2014 09:09:33 +0100 Subject: [PATCH 1/8] agch: Recalculate length limit of AGCH queue In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140302080933.GT32655@xiaoyu.lan> On Sat, Feb 22, 2014 at 12:36:02AM +0100, Jacob Erlbeck wrote: Dear Jacob, let me publicly say I think you did great work. Going from the problem description and proposal of just dropping frames you have read both the code and the specification and came up with a way better solution. I was about to merge your branch but noticed one thing. > +/* Table 3.1 TS 04.08: Values of parameter S */ > +static const uint8_t tx_integer[] = { > + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50, > +}; ... > + for (i = 0; i < 15; i++) { > + if (tx_integer[i] == T) { I didn't have breakfast yet but I think ARRAY_SIZE(tx_integer) is 16 but the last element is never looked at. Can you confirm/reject? From Ivan.Kluchnikov at fairwaves.ru Sun Mar 2 18:18:35 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Sun, 2 Mar 2014 22:18:35 +0400 Subject: [PATCH 1/8] agch: Recalculate length limit of AGCH queue In-Reply-To: <20140302080933.GT32655@xiaoyu.lan> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <20140302080933.GT32655@xiaoyu.lan> Message-ID: Hi Holger, > I didn't have breakfast yet but I think ARRAY_SIZE(tx_integer) is 16 but > the last element is never looked at. Can you confirm/reject? You are right ARRAY_SIZE(tx_integer) is 16, actually it is my mistake, Jacob just copied this part from my code. I absolutely argee with you, Jacob did great work! Also I plan to introduce patch which will support sending DELETE IND messages to BSC. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From peter at stuge.se Sun Mar 2 18:56:10 2014 From: peter at stuge.se (Peter Stuge) Date: Sun, 2 Mar 2014 19:56:10 +0100 Subject: [PATCH 1/8] agch: Recalculate length limit of AGCH queue In-Reply-To: References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <20140302080933.GT32655@xiaoyu.lan> Message-ID: <20140302185610.764.qmail@stuge.se> Ivan Kluchnikov wrote: > > I didn't have breakfast yet but I think ARRAY_SIZE(tx_integer) is 16 but > > the last element is never looked at. Can you confirm/reject? > > You are right ARRAY_SIZE(tx_integer) is 16, actually it is my mistake, You can avoid such mistakes by consistently using ARRAY_SIZE() when you want to use the size of an array. Please do. Thanks! //Peter From jerlbeck at sysmocom.de Mon Mar 3 09:43:14 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 3 Mar 2014 10:43:14 +0100 Subject: [PATCH] agch: Recalculate length limit of AGCH queue In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393839794-1308-1-git-send-email-jerlbeck@sysmocom.de> This patch adds a function bts_update_agch_max_queue_length() to compute a limit of the AGCH queue. This is based on the idea, that the AGCH queue has a limited drain rate and that CHANNEL REQUESTs must be answered within a certain time frame, given by the minimum value of T3126 (see GSM 04.08). When the AGCH queue reaches that limit, the last message would be delivered in time if there were no other delays involved (which is not the case). The calculation is based on the ratio of the number RACH slots and CCCH blocks per time: Lmax = (T + 2*S) / R_RACH * R_CCCH where T3126_min = (T + 2*S) / R_RACH R_RACH is the RACH slot rate (e.g. RACHs per multiframe) R_CCCH is the CCCH block rate (same time base like R_RACH) The value depends control_channel_desc.ccch_conf and rach_control.tx_integer (both from SYSINFO_TYPE_3) and should therefore by called at least each time after one of these is changed. For this reason, a signal callback is registered under SS_GLOBAL/S_NEW_SYSINFO which invokes bts_update_agch_max_queue_length(). Based-On: "bts: Calculate length of agch queue" by Ivan Kluchnikov --- include/osmo-bts/bts.h | 2 + include/osmo-bts/gsm_data.h | 1 + src/common/bts.c | 90 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 49ef617..d27eef0 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -26,6 +26,8 @@ void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); struct msgb *bts_agch_dequeue(struct gsm_bts *bts); +void bts_update_agch_max_queue_length(struct gsm_bts *bts); +int bts_agch_max_queue_length(int T, int bcch_conf); int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, int is_ag_res); diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index aee56a9..ea3fa5e 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -50,6 +50,7 @@ struct gsm_bts_role_bts { uint8_t max_ta; struct llist_head agch_queue; int agch_queue_length; + int agch_max_queue_length; struct paging_state *paging_state; char *bsc_oml_host; unsigned int rtp_jitter_buf_ms; diff --git a/src/common/bts.c b/src/common/bts.c index 7bbf587..e82656d 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -42,6 +42,7 @@ #include #include #include +#include struct gsm_network bts_gsmnet = { @@ -51,11 +52,32 @@ struct gsm_network bts_gsmnet = { void *tall_bts_ctx; +/* Table 3.1 TS 04.08: Values of parameter S */ +static const uint8_t tx_integer[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50, +}; + +static const uint8_t s_values[][2] = { + { 55, 41 }, { 76, 52 }, { 109, 58 }, { 163, 86 }, { 217, 115 }, +}; + +static int bts_signal_cbfn(unsigned int subsys, unsigned int signal, + void *hdlr_data, void *signal_data) +{ + if (subsys == SS_GLOBAL && signal == S_NEW_SYSINFO) { + struct gsm_bts *bts = signal_data; + + bts_update_agch_max_queue_length(bts); + } + return 0; +} + int bts_init(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb; struct gsm_bts_trx *trx; int rc; + static int initialized = 0; /* add to list of BTSs */ llist_add_tail(&bts->list, &bts_gsmnet.bts_list); @@ -110,6 +132,11 @@ int bts_init(struct gsm_bts *bts) bts_gsmnet.num_bts++; + if (!initialized) { + osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL); + initialized = 1; + } + return rc; } @@ -209,11 +236,72 @@ int lchan_init_lapdm(struct gsm_lchan *lchan) return 0; } +#define CCCH_RACH_RATIO_COMBINED256 (256*1/9) +#define CCCH_RACH_RATIO_SEPARATE256 (256*10/55) + +int bts_agch_max_queue_length(int T, int bcch_conf) +{ + int S, ccch_rach_ratio256, i; + int T_group = 0; + int is_ccch_comb = 0; + + if (bcch_conf == RSL_BCCH_CCCH_CONF_1_C) + is_ccch_comb = 1; + + /* + * The calculation is based on the ratio of the number RACH slots and + * CCCH blocks per time: + * Lmax = (T + 2*S) / R_RACH * R_CCCH + * where + * T3126_min = (T + 2*S) / R_RACH, as defined in GSM 04.08, 11.1.1 + * R_RACH is the RACH slot rate (e.g. RACHs per multiframe) + * R_CCCH is the CCCH block rate (same time base like R_RACH) + * S and T are defined in GSM 04.08, 3.3.1.1.2 + * The ratio is mainly influenced by the downlink only channels + * (BCCH, FCCH, SCH, CBCH) that can not be used for CCCH. + * An estimation with an error of < 10% is used: + * ~ 1/9 if CCCH is combined with SDCCH, and + * ~ 1/5.5 otherwise. + */ + ccch_rach_ratio256 = is_ccch_comb ? + CCCH_RACH_RATIO_COMBINED256 : + CCCH_RACH_RATIO_SEPARATE256; + + for (i = 0; i < ARRAY_SIZE(tx_integer); i++) { + if (tx_integer[i] == T) { + T_group = i % 5; + break; + } + } + S = s_values[T_group][is_ccch_comb]; + + return (T + 2 * S) * ccch_rach_ratio256 / 256; +} + +void bts_update_agch_max_queue_length(struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct gsm48_system_information_type_3 *si3; + int old_max_length = btsb->agch_max_queue_length; + + if (!(bts->si_valid & (1<agch_max_queue_length = + bts_agch_max_queue_length(si3->rach_control.tx_integer, + si3->control_channel_desc.ccch_conf); + + if (btsb->agch_max_queue_length != old_max_length) + LOGP(DRSL, LOGL_INFO, "Updated AGCH max queue length to %d\n", + btsb->agch_max_queue_length); +} + int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - /* FIXME: implement max queue length */ msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_length++; -- 1.7.9.5 From anayuso at sysmocom.de Sat Mar 22 16:15:38 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Sat, 22 Mar 2014 17:15:38 +0100 Subject: [libosmocore PATCH v2] src/socket: Adding domain socket support In-Reply-To: <20140227111627.14179.94135.stgit@Ph0enix> References: <20140227111627.14179.94135.stgit@Ph0enix> Message-ID: <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso Added some function for adding domain socket support. Signed-off-by: Alvaro Neira Ayuso --- include/osmocom/core/socket.h | 6 +++ src/socket.c | 100 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index f15a03a..cb1b7a8 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -30,6 +30,12 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type, int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen); +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + /*! @} */ #endif /* _OSMOCORE_SOCKET_H */ diff --git a/src/socket.c b/src/socket.c index 6ff00f0..8e325ba 100644 --- a/src/socket.c +++ b/src/socket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -257,6 +258,105 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen) return 0; } +/*! \brief Initialize a domain socket (including bind/connect) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates a new socket unix, \a + * type and \a proto and optionally binds or connects it, depending on + * the value of \a flags parameter. + */ +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + struct sockaddr_un local; + int sfd, rc, on = 1; + unsigned int namelen; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == + (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) + return -EINVAL; + + local.sun_family = AF_UNIX; + strncpy(local.sun_path, socket_path, sizeof(local.sun_path)); + local.sun_path[sizeof(local.sun_path) - 1] = '\0'; + +#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) + local.sun_len = strlen(local.sun_path); +#endif +#if defined(BSD44SOCKETS) || defined(SUN_LEN) + namelen = SUN_LEN(&local); +#else + namelen = strlen(local.sun_path) + + offsetof(struct sockaddr_un, sun_path); +#endif + + sfd = socket(AF_UNIX, type, proto); + if (sfd < 0) + return -1; + + if (flags & OSMO_SOCK_F_CONNECT) { + rc = connect(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) { + close(sfd); + return -1; + } + } else { + unlink(local.sun_path); + rc = bind(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) { + close(sfd); + return -1; + } + } + + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + perror("cannot set this socket unblocking"); + close(sfd); + return -EINVAL; + } + } + + if (flags & OSMO_SOCK_F_BIND) + listen(sfd, 10); + + return sfd; +} + +/*! \brief Initialize a domain socket and fill \ref osmo_fd + * \param[out] ofd file descriptor (will be filled in) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates (and optionall binds/connects) a socket using + * \ref osmo_sock_unix_init, but also fills the \a ofd structure. + */ +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + int sfd, rc; + + sfd = osmo_sock_unix_init(type, proto, socket_path, flags); + if (sfd < 0) + return sfd; + + ofd->fd = sfd; + ofd->when = BSC_FD_READ; + + rc = osmo_fd_register(ofd); + if (rc < 0) { + close(sfd); + return rc; + } + + return sfd; +} + #endif /* HAVE_SYS_SOCKET_H */ /*! @} */ -- 1.7.10.4 From holger at freyther.de Sun Mar 23 22:03:47 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 23 Mar 2014 23:03:47 +0100 Subject: [libosmocore PATCH v2] src/socket: Adding domain socket support In-Reply-To: <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> References: <20140227111627.14179.94135.stgit@Ph0enix> <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> Message-ID: <20140323220347.GX15530@xiaoyu.lan> On Sat, Mar 22, 2014 at 05:15:38PM +0100, Alvaro Neira Ayuso wrote: > +/*! \brief Initialize a domain socket (including bind/connect) to follow unix(7) maybe call it UNIX domain socket > + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM > + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP > + * This function creates a new socket unix, \a UNIX domain socket? > + > + if (flags & OSMO_SOCK_F_NONBLOCK) { > + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { > + perror("cannot set this socket unblocking"); > + close(sfd); > + return -EINVAL; > + } > + } > + > + if (flags & OSMO_SOCK_F_BIND) > + listen(sfd, 10); Do you want to check the return value of listen as well? > +/*! \brief Initialize a domain socket and fill \ref osmo_fd UNIX domain socket the actual code looks fine. Please fix the comments and send an updated patch. I would be happy to merge it tomorrow. From anayuso at sysmocom.de Mon Mar 24 12:02:00 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Mon, 24 Mar 2014 13:02:00 +0100 Subject: [libosmocore PATCH v3] src/socket: Adding unix domain socket support In-Reply-To: <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> References: <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> Message-ID: <1395662520-10131-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso Added some function for adding the unix domain socket support. Signed-off-by: Alvaro Neira Ayuso --- v3: changed the description name of the socket for following the unix(7) and checked the listen return. include/osmocom/core/socket.h | 6 +++ src/socket.c | 102 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index f15a03a..cb1b7a8 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -30,6 +30,12 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type, int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen); +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + /*! @} */ #endif /* _OSMOCORE_SOCKET_H */ diff --git a/src/socket.c b/src/socket.c index 6ff00f0..c93224a 100644 --- a/src/socket.c +++ b/src/socket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -257,6 +258,107 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen) return 0; } +/*! \brief Initialize a unix domain socket (including bind/connect) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates a new unix domain socket, \a + * type and \a proto and optionally binds or connects it, depending on + * the value of \a flags parameter. + */ +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + struct sockaddr_un local; + int sfd, rc, on = 1; + unsigned int namelen; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == + (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) + return -EINVAL; + + local.sun_family = AF_UNIX; + strncpy(local.sun_path, socket_path, sizeof(local.sun_path)); + local.sun_path[sizeof(local.sun_path) - 1] = '\0'; + +#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) + local.sun_len = strlen(local.sun_path); +#endif +#if defined(BSD44SOCKETS) || defined(SUN_LEN) + namelen = SUN_LEN(&local); +#else + namelen = strlen(local.sun_path) + + offsetof(struct sockaddr_un, sun_path); +#endif + + sfd = socket(AF_UNIX, type, proto); + if (sfd < 0) + return -1; + + if (flags & OSMO_SOCK_F_CONNECT) { + rc = connect(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) + goto err; + } else { + unlink(local.sun_path); + rc = bind(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) + goto err; + } + + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + perror("cannot set this socket unblocking"); + close(sfd); + return -EINVAL; + } + } + + if (flags & OSMO_SOCK_F_BIND) { + rc = listen(sfd, 10); + if (rc < 0) + goto err; + } + + return sfd; +err: + close(sfd); + return -1; +} + +/*! \brief Initialize a unix domain socket and fill \ref osmo_fd + * \param[out] ofd file descriptor (will be filled in) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates (and optionall binds/connects) a socket using + * \ref osmo_sock_unix_init, but also fills the \a ofd structure. + */ +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + int sfd, rc; + + sfd = osmo_sock_unix_init(type, proto, socket_path, flags); + if (sfd < 0) + return sfd; + + ofd->fd = sfd; + ofd->when = BSC_FD_READ; + + rc = osmo_fd_register(ofd); + if (rc < 0) { + close(sfd); + return rc; + } + + return sfd; +} + #endif /* HAVE_SYS_SOCKET_H */ /*! @} */ -- 1.7.10.4 From holger at freyther.de Sun Mar 2 07:24:46 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 2 Mar 2014 08:24:46 +0100 Subject: [PATCH 2/2] msgb: Optionally declare some msgb struct fields as const In-Reply-To: <1393616866-18629-2-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393616866-18629-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140302072446.GS32655@xiaoyu.lan> On Fri, Feb 28, 2014 at 08:47:46PM +0100, Jacob Erlbeck wrote: Good Morning, I welcome any change that makes it more difficult to create the mess that LAPD/LAPDm is in. I have some questions and comments though. > Writing directly to following struct fields may cause inconsistencies > that hard to debug: > In general, the available macros and functions should be used to > modify them instead. ^ must as in RFC? > This patch declares these fields as const if > MSGB_DISABLE_DIRECT_WRITE is defined. Doing so may lead to warnings > and errors, therefore this macro is only defined for libosmocore yet, > where at least the errors are also fixed by this patch. I will get back to this later as well. Have you looked at GSEAL of GTK+ 2.0? Their goal was to hide direct access to variables too and they introduced a macro like: #ifndef GSEAL /* introduce GSEAL() here for all of Gdk and Gtk+ without the need to modify GLib */ # ifdef GSEAL_ENABLE # define GSEAL(ident) _g_sealed__ ## ident # else # define GSEAL(ident) ident # endif #endif /* !GSEAL */ It is not making the variables const but hiding them with a rename and causing a compilation failure when being accessed. > -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include > +export AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -DMSGB_DISABLE_DIRECT_WRITE Is that really necessary? > +#ifdef DOXYGEN My take would be that we try to avoid direct access so we don't need to document these variables and can use \internal here. I think it is preferable to avoid the situation where the ABI changes based on an external define (even if it is just for documentation now). I have seen a lot of wild CFLAGS/CPPFLAGS that users set while working on OpenEmbedded > + const uint16_t data_len; /*!< \brief length of underlying data array */ > + const uint16_t len; /*!< \brief length of bytes used in msgb */ > + unsigned char const *head; /*!< \brief start of underlying memory buffer */ > + unsigned char const *tail; /*!< \brief end of message in buffer */ > + unsigned char const *data; /*!< \brief start of message in buffer */ > +#else > + union { > + MSGB_CONST uint16_t data_len; > + uint16_t __data_len; > + }; Anyone knows an ABI where alignment for const/non-const is different? :) cheers holger From jerlbeck at sysmocom.de Mon Mar 3 11:10:13 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 03 Mar 2014 12:10:13 +0100 Subject: [PATCH 2/2] msgb: Optionally declare some msgb struct fields as const In-Reply-To: <20140302072446.GS32655@xiaoyu.lan> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393616866-18629-2-git-send-email-jerlbeck@sysmocom.de> <20140302072446.GS32655@xiaoyu.lan> Message-ID: <53146315.4020709@sysmocom.de> Hi, On 02.03.2014 08:24, Holger Hans Peter Freyther wrote: > On Fri, Feb 28, 2014 at 08:47:46PM +0100, Jacob Erlbeck wrote: > >> Writing directly to following struct fields may cause inconsistencies >> that hard to debug: > >> In general, the available macros and functions should be used to >> modify them instead. > > ^ must as in RFC? Rather "should" as in RFC2119: SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. But I don't really see many 'particular circumstances' that would justify that. Perhaps something like: It's impossible to achieve with the existing API _and_ the current libosmocore must be used _and_ the new functionality is wrapped in a new macro/function written specifically for that purpose. Or did you mean "MUST (...)" as in RFC6919 ;-) > > I will get back to this later as well. Have you looked at GSEAL > of GTK+ 2.0? Their goal was to hide direct access to variables too > and they introduced a macro like: > > #ifndef GSEAL > /* introduce GSEAL() here for all of Gdk and Gtk+ without the need to modify GLib */ > # ifdef GSEAL_ENABLE > # define GSEAL(ident) _g_sealed__ ## ident > # else > # define GSEAL(ident) ident > # endif > #endif /* !GSEAL */ > > It is not making the variables const but hiding them with a rename > and causing a compilation failure when being accessed. I'm only addressing write access (yet), so sealing wouldn't help here. That would be different, if we was forbidding direct access to the fields completely, e.g. to make certain optimizations possible. > >> -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include >> +export AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -DMSGB_DISABLE_DIRECT_WRITE > > Is that really necessary? AM_CPPFLAGS has not been passed to the sub-makes and thus wasn't honoured at all. But I'll remove the 'include' stuff from that variable, because it had worked pretty well without them so far. > >> +#ifdef DOXYGEN > > My take would be that we try to avoid direct access so we don't need > to document these variables and can use \internal here. I think it is > preferable to avoid the situation where the ABI changes based on an > external define (even if it is just for documentation now). I have seen > a lot of wild CFLAGS/CPPFLAGS that users set while working on OpenEmbedded Ok, I didn't want to break the Doxygen output, but having inconsistent variants is worse (it's already broken, see the 'const'). I'll gladly remove it. > > Anyone knows an ABI where alignment for const/non-const is different? :) It's a qualifier only, and according to C99, 6.2.5 (23): "the qualified or unqualified versions of a type are distinct types that belong to the same type category and have the same representation and alignment requirements." and "The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions." Jacob From holger at freyther.de Sun Mar 2 07:06:17 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 2 Mar 2014 08:06:17 +0100 Subject: [PATCH 1/2] msgb: Add msgb_hexdump() function In-Reply-To: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140302070617.GR32655@xiaoyu.lan> On Fri, Feb 28, 2014 at 08:47:45PM +0100, Jacob Erlbeck wrote: Good morning Jacob, as usual thank you very much for your work. > This function works like osmo_hexdump() and return a static buffer ^ returns > containing hex bytes along with markes for the layers. ^ markers > +/*! \brief Return (static) buffer containing a hexdump of the msg ^ Return "a" > +const char *msgb_hexdump(const struct msgb *msg) > +{ > + static char buf[4100]; > + int buf_offs = 0; > + int nchars; > + const unsigned char *start = msg->data; > + const unsigned char *lxhs[4]; > + int i; > + > + lxhs[0] = msg->l1h; > + lxhs[1] = msg->l2h; > + lxhs[2] = msg->l3h; > + lxhs[3] = msg->l4h; > + > + for (i = 0; i < ARRAY_SIZE(lxhs); i++) { > + if (lxhs[i]) { if (!lxhs[i]) continue; This avoids having the show at three levels of indention in. > + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, > + "%s[L%d]> ", > + osmo_hexdump(start, lxhs[i] - start), > + i+1); > + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, > + "%s", osmo_hexdump(start, msg->tail - start)); > + nchars = snprintf(buf, sizeof(buf) - buf_offs, > + "!!! L%d out of range", i+1); So sizeof(buf) - buf_offs can only be 0 when the output is already null terminated? kind regards holger From jerlbeck at sysmocom.de Mon Mar 3 10:01:47 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 03 Mar 2014 11:01:47 +0100 Subject: [PATCH 1/2] msgb: Add msgb_hexdump() function In-Reply-To: <20140302070617.GR32655@xiaoyu.lan> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <20140302070617.GR32655@xiaoyu.lan> Message-ID: <5314530B.7070604@sysmocom.de> Dear Holger On 02.03.2014 08:06, Holger Hans Peter Freyther wrote: > >> + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, >> + "%s[L%d]> ", >> + osmo_hexdump(start, lxhs[i] - start), >> + i+1); > >> + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, >> + "%s", osmo_hexdump(start, msg->tail - start)); >> + nchars = snprintf(buf, sizeof(buf) - buf_offs, >> + "!!! L%d out of range", i+1); > > So sizeof(buf) - buf_offs can only be 0 when the output is already null > terminated? No, the expressions can never be 0 due to if (nchars < 0 || nchars + buf_offs >= sizeof(buf)) return "ERROR"; But even if it could, the string has already been \0 terminated by prior calls to snprintf (the initial size value is always > 0). Jacob > > kind regards > holger > From jerlbeck at sysmocom.de Tue Mar 4 12:44:38 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:38 +0100 Subject: [PATCH 1/6] msgb: Add msgb_hexdump() function In-Reply-To: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> This function works like osmo_hexdump() and returns a static buffer containing hex bytes along with markers for the layers. Note that it uses osmo_hexdump() internally, thus a call to msgb_hexdump() invalidates the buffer that has been returned by an earlier call to osmo_hexdump(). In short: don't mix them in a single call printf(). Sponsored-by: On-Waves ehf --- include/osmocom/core/msgb.h | 1 + src/msgb.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index fe2733b..5d4bd84 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -73,6 +73,7 @@ extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); extern struct msgb *msgb_dequeue(struct llist_head *queue); extern void msgb_reset(struct msgb *m); uint16_t msgb_length(const struct msgb *msg); +extern const char *msgb_hexdump(const struct msgb *msg); #ifdef MSGB_DEBUG #include diff --git a/src/msgb.c b/src/msgb.c index 359a545..b2fe1d2 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -153,4 +153,53 @@ void msgb_set_talloc_ctx(void *ctx) tall_msgb_ctx = ctx; } +/*! \brief Return a (static) buffer containing a hexdump of the msg + * \param[in] msg message buffer + * \returns a pointer to a static char array + */ +const char *msgb_hexdump(const struct msgb *msg) +{ + static char buf[4100]; + int buf_offs = 0; + int nchars; + const unsigned char *start = msg->data; + const unsigned char *lxhs[4]; + int i; + + lxhs[0] = msg->l1h; + lxhs[1] = msg->l2h; + lxhs[2] = msg->l3h; + lxhs[3] = msg->l4h; + + for (i = 0; i < ARRAY_SIZE(lxhs); i++) { + if (!lxhs[i]) + continue; + + if (lxhs[i] < msg->data) + goto out_of_range; + if (lxhs[i] > msg->tail) + goto out_of_range; + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, + "%s[L%d]> ", + osmo_hexdump(start, lxhs[i] - start), + i+1); + if (nchars < 0 || nchars + buf_offs >= sizeof(buf)) + return "ERROR"; + + buf_offs += nchars; + start = lxhs[i]; + } + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, + "%s", osmo_hexdump(start, msg->tail - start)); + if (nchars < 0 || nchars + buf_offs >= sizeof(buf)) + return "ERROR"; + + return buf; + +out_of_range: + nchars = snprintf(buf, sizeof(buf) - buf_offs, + "!!! L%d out of range", i+1); + return buf; +} + /*! @} */ -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 12:44:39 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:39 +0100 Subject: [PATCH 2/6] lapd/test: Show dequeued messages In-Reply-To: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-2-git-send-email-jerlbeck@sysmocom.de> This adds and uses a wrapper for lapdm_phsap_dequeue_prim() that prints information about the message that has been taken from the queue. --- tests/lapd/lapd_test.c | 86 ++++++++++++++++++++++++++++++++--------------- tests/lapd/lapd_test.ok | 18 +++++++--- 2 files changed, 72 insertions(+), 32 deletions(-) diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index b4594de..1842ab7 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -240,6 +240,51 @@ static int ms_to_bts_l1_cb(struct osmo_prim_hdr *oph, void *_ctx) return rc; } +static int dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp, + const char *queue_name) +{ + int rc; + int l2_header_len; + int l3_len = 0; + + /* Take message from queue */ + rc = lapdm_phsap_dequeue_prim(le, pp); + + fprintf(stderr, "dequeue: got rc %d: %s\n", rc, + rc <= 0 ? strerror(-rc) : "-"); + + if (rc < 0) + return rc; + + l2_header_len = msgb_l2len(pp->oph.msg); + if (msgb_l3(pp->oph.msg)) { + l3_len = msgb_l3len(pp->oph.msg); + l2_header_len -= l3_len; + } else + fprintf(stderr, "MSGB: L3 is undefined\n"); + + if (l2_header_len < 0 || l2_header_len > pp->oph.msg->data_len) { + fprintf(stderr, + "MSGB inconsistent: data = %p, l2 = %p, l3 = %p, tail = %p\n", + pp->oph.msg->data, + pp->oph.msg->l2h, + pp->oph.msg->l3h, + pp->oph.msg->tail); + l2_header_len = -1; + } + + printf("Took message from %s queue: " + "L2 header size %d, L3 size %d, " + "SAP %#x, %d/%d, Link 0x%02x\n", + queue_name, + l2_header_len, l3_len, + pp->oph.sap, pp->oph.primitive, pp->oph.operation, + pp->u.data.link_id); + printf("Message: %s\n", msgb_hexdump(pp->oph.msg)); + + return rc; +} + static int ms_to_bts_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *_ctx) { struct lapdm_polling_state *state = _ctx; @@ -315,7 +360,7 @@ static void test_lapdm_polling() /* 2. Poll on the BTS for sending out a confirmation */ printf("\nConfirming\n"); OSMO_ASSERT(test_state.bts_read == 1); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); CHECK_RC(rc); OSMO_ASSERT(pp.oph.msg->data == pp.oph.msg->l2h); send(pp.oph.msg, &ms_to_bts_channel); @@ -325,14 +370,14 @@ static void test_lapdm_polling() /* 3. Send some data to the MS */ printf("\nSending back to MS\n"); lapdm_rslms_recvmsg(create_mm_id_req(), &bts_to_ms_channel); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); CHECK_RC(rc); send(pp.oph.msg, &ms_to_bts_channel); msgb_free(pp.oph.msg); OSMO_ASSERT(test_state.ms_read == 2); /* verify that there is nothing more to poll */ - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); OSMO_ASSERT(rc < 0); /* 3. And back to the BTS */ @@ -344,14 +389,14 @@ static void test_lapdm_polling() /* 4. And back to the MS, but let's move data/l2h apart */ OSMO_ASSERT(test_state.bts_read == 2); OSMO_ASSERT(test_state.ms_read == 2); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); CHECK_RC(rc); send(pp.oph.msg, &ms_to_bts_channel); OSMO_ASSERT(test_state.ms_read == 2); msgb_free(pp.oph.msg); /* verify that there is nothing more to poll */ - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); OSMO_ASSERT(rc < 0); /* check sending an empty L3 message fails */ @@ -392,18 +437,18 @@ static void test_lapdm_contention_resolution() /* Send SABM MS 1, we must get UA */ send_sabm(&bts_to_ms_channel, 0); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); CHECK_RC(rc); OSMO_ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); /* Send SABM MS 2, we must get nothing, due to collision */ send_sabm(&bts_to_ms_channel, 1); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); OSMO_ASSERT(rc == -ENODEV); /* Send SABM MS 1 again, we must get UA gain */ send_sabm(&bts_to_ms_channel, 0); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); CHECK_RC(rc); OSMO_ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); @@ -451,7 +496,6 @@ static void lapdm_establish(const uint8_t *est_req, size_t est_req_size) struct lapdm_polling_state test_state; struct osmo_phsap_prim pp; struct msgb *msg; - const char *queue_name; /* Configure LAPDm on both sides */ struct lapdm_channel bts_to_ms_channel; @@ -473,31 +517,17 @@ static void lapdm_establish(const uint8_t *est_req, size_t est_req_size) OSMO_ASSERT(rc == 0); /* Take message from queue */ - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); - if (rc >= 0) - queue_name = "DCCH"; - else { - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp); - if (rc >= 0) - queue_name = "ACCH"; - } + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); + if (rc < 0) + rc = dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp, "ACCH"); - fprintf(stderr, "dequeue: got rc %d: %s\n", rc, - rc <= 0 ? strerror(-rc) : "-"); CHECK_RC(rc); - printf("Took message from %s queue: L2 header size %d, " - "SAP %#x, %d/%d, Link 0x%02x\n", - queue_name, msgb_l2len(pp.oph.msg) - msgb_l3len(pp.oph.msg), - pp.oph.sap, pp.oph.primitive, pp.oph.operation, - pp.u.data.link_id); - printf("Message: %s\n", osmo_hexdump(pp.oph.msg->data, pp.oph.msg->len)); - OSMO_ASSERT(pp.oph.msg->data == msgb_l2(pp.oph.msg)); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); OSMO_ASSERT(rc < 0); - rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp, "ACCH"); OSMO_ASSERT(rc < 0); /* clean up */ diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e4b1359..9fb58e0 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -5,10 +5,14 @@ bts_to_ms_tx_cb: MS->BTS(us) message 25 BTS: Verifying CM request. Confirming +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x00 +Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b ms_to_bts_tx_cb: BTS->MS(us) message 9 MS: Verifying incoming primitive. Sending back to MS +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x00 +Message: [L2]> 03 00 0d [L3]> 05 04 0d 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ms_to_bts_tx_cb: BTS->MS(us) message 12 MS: Verifying incoming MM message: 3 ms_to_bts_l1_cb: MS(us) -> BTS prim message @@ -17,15 +21,21 @@ Sending back to BTS ms_to_bts_l1_cb: MS(us) -> BTS prim message bts_to_ms_tx_cb: MS->BTS(us) message 14 BTS: Verifying dummy message. +Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x00 +Message: [L2]> 01 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b I test RF channel release of an unestablished channel. I test contention resultion by having two mobiles collide and first mobile repeating SABM. bts_to_ms_tx_cb: MS->BTS(us) message 25 BTS: Verifying CM request. +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x00 +Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x00 +Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b I test RF channel establishment. Testing SAPI3/SDCCH -Took message from DCCH queue: L2 header size 3, SAP 0x1000000, 0/0, Link 0x03 -Message: 0f 3f 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x03 +Message: [L2]> 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Testing SAPI3/SACCH -Took message from ACCH queue: L2 header size 5, SAP 0x1000000, 0/0, Link 0x43 -Message: 00 00 0f 3f 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from ACCH queue: L2 header size 5, L3 size 18, SAP 0x1000000, 0/0, Link 0x43 +Message: [L2]> 00 00 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Success. -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 12:44:40 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:40 +0100 Subject: [PATCH 3/6] lapd/test: Extend test case to test msgs having data before l2h In-Reply-To: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-3-git-send-email-jerlbeck@sysmocom.de> Since e.g. the IPA input driver leaves it's specific header in front of msg->l2h, so that msg->l2h != msg->data. The lapdm code does not expect this at least in rslms_rx_rll_est_req(). This patch modifies the test program to add a dummy L1 header to generated messages (unless the test would abort when doing so). Note that the ok file reflects the current state which is not correct. Sponsored-by: On-Waves ehf --- tests/lapd/lapd_test.c | 12 ++++++++++++ tests/lapd/lapd_test.ok | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index 1842ab7..e3d4e80 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -36,6 +36,7 @@ } static struct log_info info = {}; +static int dummy_l1_header_len = 0; struct lapdm_polling_state { struct lapdm_channel *bts; @@ -94,6 +95,7 @@ static struct msgb *create_cm_serv_req(void) msg = msgb_from_array(cm, sizeof(cm)); rsl_rll_push_l3(msg, RSL_MT_EST_REQ, 0, 0, 1); + msgb_push(msg, dummy_l1_header_len); return msg; } @@ -106,6 +108,7 @@ static struct msgb *create_mm_id_req(void) OSMO_ASSERT(msgb_l2len(msg) == 12); msg->l3h = msg->l2h + 6; OSMO_ASSERT(msgb_l3len(msg) == 6); + msgb_push(msg, dummy_l1_header_len); return msg; } @@ -117,6 +120,7 @@ static struct msgb *create_empty_msg(void) msg = msgb_from_array(NULL, 0); OSMO_ASSERT(msgb_l3len(msg) == 0); rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); + msgb_push(msg, dummy_l1_header_len); return msg; } @@ -126,6 +130,7 @@ static struct msgb *create_dummy_data_req(void) msg = msgb_from_array(dummy1, sizeof(dummy1)); rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); + msgb_push(msg, dummy_l1_header_len); return msg; } @@ -135,6 +140,7 @@ static struct msgb *create_rel_req(void) msg = msgb_from_array(rel_req, sizeof(rel_req)); msg->l2h = msg->data; + msgb_push(msg, dummy_l1_header_len); msg->l3h = msg->l2h + sizeof(struct abis_rsl_rll_hdr); return msg; } @@ -145,6 +151,7 @@ static struct msgb *create_est_req(const uint8_t *est_req, size_t est_req_size) msg = msgb_from_array(est_req, est_req_size); msg->l2h = msg->data; + msgb_push(msg, dummy_l1_header_len); msg->l3h = msg->l2h + sizeof(struct abis_rsl_rll_hdr); return msg; } @@ -550,10 +557,15 @@ int main(int argc, char **argv) { osmo_init_logging(&info); + /* Prevent the test from segfaulting */ + dummy_l1_header_len = 0; test_lapdm_polling(); + + dummy_l1_header_len = 3; test_lapdm_early_release(); test_lapdm_contention_resolution(); test_lapdm_establishment(); + printf("Success.\n"); return 0; diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index 9fb58e0..7d266bd 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -33,9 +33,9 @@ Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b I test RF channel establishment. Testing SAPI3/SDCCH -Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x03 -Message: [L2]> 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from DCCH queue: L2 header size 6, L3 size 17, SAP 0x1000000, 0/0, Link 0x03 +Message: [L2]> 0f 3f 0d 20 02 03 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Testing SAPI3/SACCH -Took message from ACCH queue: L2 header size 5, L3 size 18, SAP 0x1000000, 0/0, Link 0x43 -Message: [L2]> 00 00 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from ACCH queue: L2 header size 8, L3 size 15, SAP 0x1000000, 0/0, Link 0x43 +Message: [L2]> 00 00 0f 3f 0d 0b 02 43 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Success. -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 12:44:41 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:41 +0100 Subject: [PATCH 4/6] lapd/test: Check for empty ACCH queue, too In-Reply-To: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-4-git-send-email-jerlbeck@sysmocom.de> This just adds a single test to verify that the ACCH queue is actually empty. Sponsored-by: On-Waves ehf --- tests/lapd/lapd_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e3d4e80..6b5cfd3 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -405,6 +405,8 @@ static void test_lapdm_polling() /* verify that there is nothing more to poll */ rc = dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp, "DCCH"); OSMO_ASSERT(rc < 0); + rc = dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp, "ACCH"); + OSMO_ASSERT(rc < 0); /* check sending an empty L3 message fails */ rc = lapdm_rslms_recvmsg(create_empty_msg(), &bts_to_ms_channel); -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 12:44:42 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:42 +0100 Subject: [PATCH 5/6] ladpm: Fix msgb handling and SAPI=3 establishment delay In-Reply-To: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-5-git-send-email-jerlbeck@sysmocom.de> Currently it takes 3s to establish a SAPI 3 SACCH connection with osmo-bts. This is due to the fact, that a broken SABME request is sent first and and is ignored by the MS. Then, after a T200 timeout (2s) the SABME command is sent again (this time correctly) and answered by the MS. The first SABME message is broken (it has a length field of 3 and ends with 3 bytes from the tail of the original RSL message), because of it is expected throughout lapdm.c that msg buffers containing RSL have msg->l2h == msg->data. Some abis input drivers fulfill this but IPA doesn't, thus the 3 bytes of the IPA header are still part of the msg and confuse length computation. Since internal fields of the msg are modified directly, this is difficult to see. This patch adds a new function msgb_pull_to_l3() that explicitely skips over all headers prepending L3 and therefore resets l1h and l2h. This function is then used instead of msgb_pull_l2h() which only worked correctly when msg->l2h == msg->data. In addition, code manipulating msg->tail and msg->len directly has been replaced by calls to msgb_trim(). Note that this patch does not fix all issues of this case in the LADP related code. Ticket: #192 Sponsored-by: On-Waves ehf --- include/osmocom/core/msgb.h | 15 +++++++++++++++ src/gsm/lapdm.c | 41 ++++++++++++++--------------------------- tests/lapd/lapd_test.ok | 8 ++++---- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 5d4bd84..33e8081 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -300,6 +300,21 @@ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) return msgb->data += len; } +/*! \brief remove (pull) all headers in front of l3h from the message buffer. + * \param[in] msgb message buffer with a valid l3h + * \returns pointer to new start of msgb (l3h) + * + * This function moves the \a data pointer of the \ref msgb further back + * in the message, thereby shrinking the size of the message. + * l1h and l2h will be cleared. + */ +static inline unsigned char *msgb_pull_to_l3(struct msgb *msg) +{ + unsigned char *ret = msgb_pull(msg, msg->l3h - msg->data); + msg->l1h = msg->l2h = NULL; + return ret; +} + /*! \brief remove uint8 from front of message * \param[in] msgb message buffer * \returns 8bit value taken from end of msgb diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 19f78a1..41f4be7 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -193,14 +193,6 @@ static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t } } -/* remove the L2 header from a MSGB */ -static inline unsigned char *msgb_pull_l2h(struct msgb *msg) -{ - unsigned char *ret = msgb_pull(msg, msg->l3h - msg->l2h); - msg->l2h = NULL; - return ret; -} - /* Append padding (if required) */ static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201) { @@ -611,7 +603,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, lctx.length = n201; lctx.more = 0; msg->l3h = msg->l2h + 2; - msgb_pull_l2h(msg); + msgb_pull_to_l3(msg); } else { /* length field */ if (!(msg->l2h[2] & LAPDm_EL)) { @@ -629,7 +621,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, lctx.length = msg->l2h[2] >> 2; lctx.more = !!(msg->l2h[2] & LAPDm_MORE); msg->l3h = msg->l2h + 3; - msgb_pull_l2h(msg); + msgb_pull_to_l3(msg); } /* store context for messages from lapd */ memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx)); @@ -644,7 +636,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, /* directly pass up to layer3 */ LOGP(DLLAPD, LOGL_INFO, "fmt=Bbis UI\n"); msg->l3h = msg->l2h; - msgb_pull_l2h(msg); + msgb_pull_to_l3(msg); rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg); break; default: @@ -807,9 +799,8 @@ static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl) } /* Remove RLL header from msgb and set length to L3-info */ - msgb_pull_l2h(msg); - msg->len = length; - msg->tail = msg->l3h + length; + msgb_pull_to_l3(msg); + msgb_trim(msg, length); /* prepare prim */ osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg); @@ -861,9 +852,8 @@ static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl) le->tx_power, le->ta); /* Remove RLL header from msgb and set length to L3-info */ - msgb_pull_l2h(msg); - msg->len = length; - msg->tail = msg->l3h + length; + msgb_pull_to_l3(msg); + msgb_trim(msg, length); /* Push L1 + LAPDm header on msgb */ msg->l2h = msgb_push(msg, 2 + !ui_bts); @@ -900,9 +890,8 @@ static int rslms_rx_rll_data_req(struct msgb *msg, struct lapdm_datalink *dl) length = TLVP_LEN(&tv, RSL_IE_L3_INFO); /* Remove RLL header from msgb and set length to L3-info */ - msgb_pull_l2h(msg); - msg->len = length; - msg->tail = msg->l3h + length; + msgb_pull_to_l3(msg); + msgb_trim(msg, length); /* prepare prim */ osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg); @@ -957,9 +946,8 @@ static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl) length = TLVP_LEN(&tv, RSL_IE_L3_INFO); /* Remove RLL header from msgb and set length to L3-info */ - msgb_pull_l2h(msg); - msg->len = length; - msg->tail = msg->l3h + length; + msgb_pull_to_l3(msg); + msgb_trim(msg, length); /* prepare prim */ osmo_prim_init(&dp.oph, 0, (msg_type == RSL_MT_RES_REQ) ? PRIM_DL_RES @@ -981,12 +969,11 @@ static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl) mode = rllh->data[1] & 1; /* Pull rllh */ - msgb_pull_l2h(msg); + msgb_pull_to_l3(msg); /* 04.06 3.8.3: No information field is permitted with the DISC * command. */ - msg->len = 0; - msg->tail = msg->l3h = msg->data; + msgb_trim(msg, 0); /* prepare prim */ osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg); @@ -1045,7 +1032,7 @@ static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t f gsm_fn2gsmtime(&tm, frame_nr); - msgb_pull_l2h(msg); + msgb_pull_to_l3(msg); msg->l2h = msgb_push(msg, sizeof(*ch) + sizeof(*ref)); ch = (struct abis_rsl_cchan_hdr *)msg->l2h; rsl_init_cchan_hdr(ch, RSL_MT_CHAN_CONF); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index 7d266bd..9fb58e0 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -33,9 +33,9 @@ Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b I test RF channel establishment. Testing SAPI3/SDCCH -Took message from DCCH queue: L2 header size 6, L3 size 17, SAP 0x1000000, 0/0, Link 0x03 -Message: [L2]> 0f 3f 0d 20 02 03 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x03 +Message: [L2]> 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Testing SAPI3/SACCH -Took message from ACCH queue: L2 header size 8, L3 size 15, SAP 0x1000000, 0/0, Link 0x43 -Message: [L2]> 00 00 0f 3f 0d 0b 02 43 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Took message from ACCH queue: L2 header size 5, L3 size 18, SAP 0x1000000, 0/0, Link 0x43 +Message: [L2]> 00 00 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Success. -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 12:44:43 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 4 Mar 2014 13:44:43 +0100 Subject: [PATCH 6/6] msgb: Optionally declare some msgb struct fields as const In-Reply-To: <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393937083-2337-6-git-send-email-jerlbeck@sysmocom.de> Writing directly to following struct fields may cause inconsistencies that are hard to debug: data_len, len, head, tail, data In general, the available macros and functions should be used to modify them instead. This patch declares these fields as const if MSGB_DISABLE_DIRECT_WRITE is defined. Doing so may lead to warnings and errors, therefore this macro is only defined for libosmocore yet, where at least the errors are also fixed by this patch. The main purpose is to maintain consistency, so only modifing the fields themselves is restricted. It's still possible to modify the data the pointers refer to. Sponsored-by: On-Waves ehf --- Doxyfile.core.in | 2 +- Makefile.am | 3 +- include/osmocom/core/msgb.h | 66 +++++++++++++++++++++++++++++------------- src/msgb.c | 20 ++++++------- tests/gsm0808/gsm0808_test.c | 3 +- 5 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Doxyfile.core.in b/Doxyfile.core.in index 71843cc..eecd123 100644 --- a/Doxyfile.core.in +++ b/Doxyfile.core.in @@ -1447,7 +1447,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/Makefile.am b/Makefile.am index a77bd8f..d6a1992 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +export AM_CPPFLAGS = -DMSGB_DISABLE_DIRECT_WRITE + SUBDIRS = include src src/vty src/codec src/gsm src/gb tests utils pkgconfigdir = $(libdir)/pkgconfig diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 33e8081..3593309 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -38,6 +38,12 @@ #define MSGB_DEBUG +#ifdef MSGB_DISABLE_DIRECT_WRITE +# define MSGB_CONST const +#else +# define MSGB_CONST +#endif + /*! \brief Osmocom message buffer */ struct msgb { struct llist_head list; /*!< \brief linked list header */ @@ -58,12 +64,32 @@ struct msgb { unsigned long cb[5]; /*!< \brief control buffer */ - uint16_t data_len; /*!< \brief length of underlying data array */ - uint16_t len; /*!< \brief length of bytes used in msgb */ + union { + /*! \brief length of underlying data array */ + MSGB_CONST uint16_t data_len; + uint16_t __data_len; + }; + union { + /*! \brief length of bytes used in msgb */ + MSGB_CONST uint16_t len; + uint16_t __len; + }; + union { + /*! \brief start of underlying memory buffer */ + unsigned char * MSGB_CONST head; + unsigned char *__head; + }; + union { + /*! \brief end of message in buffer */ + unsigned char * MSGB_CONST tail; + unsigned char *__tail; + }; + union { + /*! \brief start of message in buffer */ + unsigned char * MSGB_CONST data; + unsigned char *__data; + }; - unsigned char *head; /*!< \brief start of underlying memory buffer */ - unsigned char *tail; /*!< \brief end of message in buffer */ - unsigned char *data; /*!< \brief start of message in buffer */ unsigned char _data[0]; /*!< \brief optional immediate data array */ }; @@ -179,12 +205,12 @@ static inline int msgb_headroom(const struct msgb *msgb) */ static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len) { - unsigned char *tmp = msgb->tail; + unsigned char *tmp = msgb->__tail; if (msgb_tailroom(msgb) < (int) len) MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", msgb_tailroom(msgb), len); - msgb->tail += len; - msgb->len += len; + msgb->__tail += len; + msgb->__len += len; return tmp; } @@ -228,12 +254,12 @@ static inline void msgb_put_u32(struct msgb *msgb, uint32_t word) */ static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len) { - unsigned char *tmp = msgb->data - len; + unsigned char *tmp = msgb->__data - len; if (msgb_length(msgb) < len) MSGB_ABORT(msgb, "msgb too small to get %u (len %u)\n", len, msgb_length(msgb)); - msgb->tail -= len; - msgb->len -= len; + msgb->__tail -= len; + msgb->__len -= len; return tmp; } /*! \brief remove uint8 from end of message @@ -281,9 +307,9 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) if (msgb_headroom(msgb) < (int) len) MSGB_ABORT(msgb, "Not enough headroom msgb_push (%u < %u)\n", msgb_headroom(msgb), len); - msgb->data -= len; - msgb->len += len; - return msgb->data; + msgb->__data -= len; + msgb->__len += len; + return msgb->__data; } /*! \brief remove (pull) a header from the front of the message buffer * \param[in] msgb message buffer @@ -296,8 +322,8 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) */ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) { - msgb->len -= len; - return msgb->data += len; + msgb->__len -= len; + return msgb->__data += len; } /*! \brief remove (pull) all headers in front of l3h from the message buffer. @@ -356,8 +382,8 @@ static inline uint32_t msgb_pull_u32(struct msgb *msgb) */ static inline void msgb_reserve(struct msgb *msg, int len) { - msg->data += len; - msg->tail += len; + msg->__data += len; + msg->__tail += len; } /*! \brief Trim the msgb to a given absolute length @@ -370,8 +396,8 @@ static inline int msgb_trim(struct msgb *msg, int len) if (len > msg->data_len) return -1; - msg->len = len; - msg->tail = msg->data + len; + msg->__len = len; + msg->__tail = msg->__data + len; return 0; } diff --git a/src/msgb.c b/src/msgb.c index b2fe1d2..1106824 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -55,11 +55,11 @@ struct msgb *msgb_alloc(uint16_t size, const char *name) return NULL; } - msg->data_len = size; - msg->len = 0; - msg->data = msg->_data; - msg->head = msg->_data; - msg->tail = msg->_data; + msg->__data_len = size; + msg->__len = 0; + msg->__data = msg->_data; + msg->__head = msg->_data; + msg->__tail = msg->_data; return msg; } @@ -113,10 +113,10 @@ struct msgb *msgb_dequeue(struct llist_head *queue) */ void msgb_reset(struct msgb *msg) { - msg->len = 0; - msg->data = msg->_data; - msg->head = msg->_data; - msg->tail = msg->_data; + msg->__len = 0; + msg->__data = msg->_data; + msg->__head = msg->_data; + msg->__tail = msg->_data; msg->trx = NULL; msg->lchan = NULL; @@ -133,7 +133,7 @@ void msgb_reset(struct msgb *msg) */ uint8_t *msgb_data(const struct msgb *msg) { - return msg->data; + return msg->__data; } /*! \brief get length of message buffer diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 7e5e97b..1ce6ef9 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -108,8 +108,7 @@ static void test_create_cipher_complete() msgb_free(msg); /* with l3 data but short */ - l3->len -= 1; - l3->tail -= 1; + msgb_trim(l3, l3->len - 1); msg = gsm0808_create_cipher_complete(l3, 4); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Mar 4 13:01:01 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 04 Mar 2014 14:01:01 +0100 Subject: [PATCH 6/6] msgb: Optionally declare some msgb struct fields as const In-Reply-To: <1393937083-2337-6-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-1-git-send-email-jerlbeck@sysmocom.de> <1393937083-2337-6-git-send-email-jerlbeck@sysmocom.de> Message-ID: <5315CE8D.9040701@sysmocom.de> On 04.03.2014 13:44, Jacob Erlbeck wrote: > diff --git a/Doxyfile.core.in b/Doxyfile.core.in > index 71843cc..eecd123 100644 > --- a/Doxyfile.core.in > +++ b/Doxyfile.core.in > @@ -1447,7 +1447,7 @@ INCLUDE_FILE_PATTERNS = > # undefined via #undef or recursively expanded use the := operator > # instead of the = operator. > > -PREDEFINED = > +PREDEFINED = DOXYGEN > > # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then > # this tag can be used to specify a list of macro names that should be expanded. Don't merge this hunk, please. (It's already removed in the branch) Jacob From george.news at gmx.net Tue Mar 4 13:15:00 2014 From: george.news at gmx.net (George News) Date: Tue, 04 Mar 2014 14:15:00 +0100 Subject: Support for binary SMS (GSM 03.48) Message-ID: <5315D1D4.6020703@gmx.net> Hi all, ?Is it possible to use the OpenBSC system to send binary SMS? If yes how? and if not could you please point me on how to start the development? I know using the monitor app with the motorola phone is possible to send sms and make calls. Now I want to send binary SMS (03.48). TA. Jorge From holger at freyther.de Tue Mar 4 19:31:53 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 4 Mar 2014 20:31:53 +0100 Subject: Support for binary SMS (GSM 03.48) In-Reply-To: <5315D1D4.6020703@gmx.net> References: <5315D1D4.6020703@gmx.net> Message-ID: <20140304193153.GG4828@xiaoyu.lan> On Tue, Mar 04, 2014 at 02:15:00PM +0100, George News wrote: > Hi all, Hi, > I know using the monitor app with the motorola phone is possible to send > sms and make calls. Now I want to send binary SMS (03.48). you can use the SMPP interface to send binary SMS. holger From george.news at gmx.net Tue Mar 4 20:10:48 2014 From: george.news at gmx.net (George News) Date: Tue, 04 Mar 2014 21:10:48 +0100 Subject: Support for binary SMS (GSM 03.48) In-Reply-To: <20140304193153.GG4828@xiaoyu.lan> References: <5315D1D4.6020703@gmx.net> <20140304193153.GG4828@xiaoyu.lan> Message-ID: <53163348.5030708@gmx.net> So it is already implemented and I can therefore send messages to the my STK application in the SIM card. Could you please give me an extra hint about the library or application I have to run. I'm quite new to the environment. Thanks in advance Jorge On 04/03/2014 20:31, Holger Hans Peter Freyther wrote: > On Tue, Mar 04, 2014 at 02:15:00PM +0100, George News wrote: >> Hi all, > > Hi, > >> I know using the monitor app with the motorola phone is possible to send >> sms and make calls. Now I want to send binary SMS (03.48). > > you can use the SMPP interface to send binary SMS. > > > holger > > From laforge at gnumonks.org Wed Mar 5 21:04:06 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 5 Mar 2014 22:04:06 +0100 Subject: Support for binary SMS (GSM 03.48) In-Reply-To: <53163348.5030708@gmx.net> References: <5315D1D4.6020703@gmx.net> <20140304193153.GG4828@xiaoyu.lan> <53163348.5030708@gmx.net> Message-ID: <20140305210406.GW9475@nataraja> On Tue, Mar 04, 2014 at 09:10:48PM +0100, George News wrote: > Could you please give me an extra hint about the library or application > I have to run. I'm quite new to the environment. If you're not familiar with the network side of GSM, I suggest you simply send a binary SMS from one phone (attached to OpenBSC) to another phone (also attached to OpenBSC). This is implemented for 7bit/ucs2/binary SMS. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From robert.light at gmx.de Fri Mar 7 09:03:46 2014 From: robert.light at gmx.de (Robert Light) Date: Fri, 7 Mar 2014 10:03:46 +0100 Subject: Support for binary SMS (GSM 03.48) In-Reply-To: References: Message-ID: Hi, I am also interested in being able to send SMS messages. Harald, the question is interesting, as I not only want to send "normal" messages but also "special" messages, like silent SMS, or messages formatted with ie SharpSMS. https://github.com/pbansky/SharpSMS I know that there are applications for mobile devices allowing to format these kind of SMS messages but this can be done much easier if we could do it from a PC. I am also interested in how can it be done with OpenBSC and OpenBTS. Robert > Date: Wed, 5 Mar 2014 22:04:06 +0100 > From: Harald Welte > To: George News > Cc: Holger Hans Peter Freyther , > openbsc at lists.osmocom.org > Subject: Re: Support for binary SMS (GSM 03.48) > > On Tue, Mar 04, 2014 at 09:10:48PM +0100, George News wrote: > > Could you please give me an extra hint about the library or application > > I have to run. I'm quite new to the environment. > > If you're not familiar with the network side of GSM, I suggest you > simply send a binary SMS from one phone (attached to OpenBSC) to another > phone (also attached to OpenBSC). This is implemented for > 7bit/ucs2/binary SMS. > From openbsc-bounces at lists.osmocom.org Thu Mar 6 07:00:09 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Thu, 06 Mar 2014 08:00:09 +0100 Subject: 2 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 2 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From alexander.chemeris at gmail.com Thu Mar 6 14:53:13 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 6 Mar 2014 15:53:13 +0100 Subject: [PATCH] bsc,nitb: Store rf_ctrl in the net structure in osmo-nitb. Message-ID: Hi all, Prevent crash introduced in the a9fae1ae commit. Call "show network" in the NITB VTY without any BTS connected to reproduce the crash. Before it was stored in a local variable, but accessed from a net structure in the msc_signal_handler(). -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-bsc-nitb-Store-rf_ctrl-in-the-net-structure-in-osmo-.patch Type: text/x-patch Size: 1953 bytes Desc: not available URL: From ciaby at autistici.org Thu Mar 6 16:20:55 2014 From: ciaby at autistici.org (Ciaby) Date: Thu, 06 Mar 2014 17:20:55 +0100 Subject: [PATCH] nitb: Add a test for "show network" in the python testsuite. Message-ID: <5318A067.1050406@autistici.org> Added to detect breakage in the VTY interface, caused by: a9fae1ae66df57f76a0aedbd0b56228959d37d56 bsc: rf_ctrl will always be created, remove the NULL checks --- openbsc/tests/vty_test_runner.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 7c8fe8c..9975d85 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -248,6 +248,10 @@ class TestVTYNITB(TestVTYGenericBSC): res = self.vty.command("show paging-group 0 1234567") self.assertEquals(res, "%Paging group for IMSI 1234567 on BTS #0 is 7") + def testShowNetwork(self): + res = self.vty.command("show network") + self.assert_(res.startswith('BSC is on Country Code') >= 0) + class TestVTYBSC(TestVTYGenericBSC): def vty_command(self): -- 1.7.9.5 From alexander.chemeris at gmail.com Fri Mar 7 19:11:06 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 20:11:06 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. Message-ID: - Use time_t instead of abstract minutes to store validity time to make sure we support all possible values. - Return UNIX time from it to support both relative and absolute expire times. - Pass a current time to gsm340_validity_period() to compute the absolute expire time if a relative time is specified. What time is "current" is to b - We also introduce SMS_DEFAULT_VALIDITY_PERIOD macros to reduce number of magic values. PS This is a first patch of a series of patches which fix SMS validity time decoding. I'm cleaning the patch set and want to see if this patch is fine, as other patches rely on it. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Proper-decoding-and-storage-of-SMS-validity-peri.patch Type: text/x-patch Size: 6164 bytes Desc: not available URL: From alexander.chemeris at gmail.com Mon Mar 10 19:14:14 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 10 Mar 2014 20:14:14 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: Message-ID: Hi Daniel, Holger, Have you had any luck reviewing this patchset (achemeris/sms-validity branch in git)? On Fri, Mar 7, 2014 at 8:11 PM, Alexander Chemeris wrote: > - Use time_t instead of abstract minutes to store validity time to make sure > we support all possible values. > - Return UNIX time from it to support both relative and absolute expire > times. > - Pass a current time to gsm340_validity_period() to compute the absolute > expire time if a relative time is specified. What time is "current" is to b > - We also introduce SMS_DEFAULT_VALIDITY_PERIOD macros to reduce number of > magic values. > > PS This is a first patch of a series of patches which fix SMS validity time > decoding. I'm cleaning the patch set and want to see if this patch is fine, > as other patches rely on it. > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From dwillmann at sysmocom.de Tue Mar 11 19:26:02 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Tue, 11 Mar 2014 20:26:02 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: Message-ID: <20140311192602.GE27543@adrastea.totalueberwachung.de> Hello, a few comments inline. On Fri, 2014-03-07 at 20:11, Alexander Chemeris wrote: > PS This is a first patch of a series of patches which fix SMS validity time > decoding. I'm cleaning the patch set and want to see if this patch is fine, > as other patches rely on it. > From 840b7ca3efa834a0d02e4e32f62d3dac63c6bac6 Mon Sep 17 00:00:00 2001 > From: Alexander Chemeris > Date: Tue, 26 Nov 2013 16:43:10 -0600 > Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. > > - Use time_t instead of abstract minutes to store validity time to make sure we support all possible values. > - Return UNIX time from it to support both relative and absolute expire times. > - Pass a current time to gsm340_validity_period() to compute the absolute expire time if a relative time is specified. What time is "current" is to be decided by callers. > - We also introduce SMS_DEFAULT_VALIDITY_PERIOD macros to reduce number of magic values. > --- > include/osmocom/gsm/gsm0411_utils.h | 7 ++-- > src/gsm/gsm0411_utils.c | 62 +++++++++++++++-------------------- > 2 files changed, 31 insertions(+), 38 deletions(-) > > diff --git a/include/osmocom/gsm/gsm0411_utils.h b/include/osmocom/gsm/gsm0411_utils.h > index ad368e6..cad3625 100644 > --- a/include/osmocom/gsm/gsm0411_utils.h > +++ b/include/osmocom/gsm/gsm0411_utils.h > @@ -3,6 +3,9 @@ > > #include > > +/* Default SMS validity period is 2 days */ > +#define SMS_DEFAULT_VALIDITY_PERIOD (2 * 24 * 60 * 60) > + > /* Turn int into semi-octet representation: 98 => 0x89 */ > uint8_t gsm411_bcdify(uint8_t value); > > @@ -17,8 +20,8 @@ void gsm340_gen_scts(uint8_t *scts, time_t time); > /* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */ > time_t gsm340_scts(uint8_t *scts); > > -/* decode validity period. return minutes */ > -unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp); > +/* decode validity period. return absolute time */ > +time_t gsm340_validity_period(time_t now, uint8_t sms_vpf, uint8_t *sms_vp); > > /* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */ > enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs); > diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c > index a8ba810..1a6862b 100644 > --- a/src/gsm/gsm0411_utils.c > +++ b/src/gsm/gsm0411_utils.c > @@ -34,6 +34,7 @@ > > #include > #include > +#include > #include > #include > > @@ -121,16 +122,14 @@ time_t gsm340_scts(uint8_t *scts) > } > > /* Return the default validity period in minutes */ You need to update the comment. > -static unsigned long gsm340_vp_default(void) > +static time_t gsm340_vp_default(time_t now) > { > - unsigned long minutes; > /* Default validity: two days */ > - minutes = 24 * 60 * 2; > - return minutes; > + return now + SMS_DEFAULT_VALIDITY_PERIOD; > } > > /* Decode validity period format 'relative' */ > -static unsigned long gsm340_vp_relative(uint8_t *sms_vp) > +static unsigned long gsm340_vp_relative(time_t now, uint8_t *sms_vp) You should probably return time_t here as well. Also the variable minutes should become time_t as well. > { > /* Chapter 9.2.3.12.1 */ > uint8_t vp; > @@ -145,58 +144,49 @@ static unsigned long gsm340_vp_relative(uint8_t *sms_vp) > minutes = vp-166 * 60 * 24; > else > minutes = vp-192 * 60 * 24 * 7; > - return minutes; > + > + /* Calculate absolute time from the relative offset */ > + return now + minutes * 60; > } > > /* Decode validity period format 'absolute' */ > -static unsigned long gsm340_vp_absolute(uint8_t *sms_vp) > +static time_t gsm340_vp_absolute(uint8_t *sms_vp) > { > /* Chapter 9.2.3.12.2 */ > - time_t expires, now; > - unsigned long minutes; > - > - expires = gsm340_scts(sms_vp); > - now = time(NULL); > - if (expires <= now) > - minutes = 0; > - else > - minutes = (expires-now)/60; > - return minutes; > + return gsm340_scts(sms_vp); > } > > /* Decode validity period format 'relative in integer representation' */ > -static unsigned long gsm340_vp_relative_integer(uint8_t *sms_vp) > +static time_t gsm340_vp_relative_integer(time_t now, uint8_t *sms_vp) > { > uint8_t vp; > - unsigned long minutes; > vp = *(sms_vp); > if (vp == 0) { > LOGP(DLSMS, LOGL_ERROR, > "reserved relative_integer validity period\n"); > - return gsm340_vp_default(); > + return gsm340_vp_default(now); Please add a comment (with FIXME) or #warning that we should return an RP-Error here. > } > - minutes = vp/60; > - return minutes; > + return now + vp; > } > > /* Decode validity period format 'relative in semi-octet representation' */ > -static unsigned long gsm340_vp_relative_semioctet(uint8_t *sms_vp) > +static time_t gsm340_vp_relative_semioctet(time_t now, uint8_t *sms_vp) > { > - unsigned long minutes; > - minutes = gsm411_unbcdify(*sms_vp++)*60; /* hours */ > - minutes += gsm411_unbcdify(*sms_vp++); /* minutes */ > - minutes += gsm411_unbcdify(*sms_vp++)/60; /* seconds */ > - return minutes; > + unsigned long hours, minutes, seconds; time_t? > + hours = gsm411_unbcdify(*sms_vp++); /* hours */ > + minutes = gsm411_unbcdify(*sms_vp++); /* minutes */ > + seconds = gsm411_unbcdify(*sms_vp++); /* seconds */ > + return now + hours*60*60 + minutes*60 + seconds; > } > > /* decode validity period. return minutes */ The comment is wrong now > -unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp) > +time_t gsm340_validity_period(time_t now, uint8_t sms_vpf, uint8_t *sms_vp) > { > uint8_t fi; /* functionality indicator */ > > switch (sms_vpf) { > case GSM340_TP_VPF_RELATIVE: > - return gsm340_vp_relative(sms_vp); > + return gsm340_vp_relative(now, sms_vp); You could also omit now in all the static function and return now + func() in gsm340_validity_period(). That looks slightly cleaner to me and shouldn't change testability. > case GSM340_TP_VPF_ABSOLUTE: > return gsm340_vp_absolute(sms_vp); > case GSM340_TP_VPF_ENHANCED: > @@ -207,23 +197,23 @@ unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp) > /* read validity period format */ > switch (fi & 0x7) { > case 0x0: > - return gsm340_vp_default(); /* no vpf specified */ > + return gsm340_vp_default(now); /* no vpf specified */ > case 0x1: > - return gsm340_vp_relative(sms_vp); > + return gsm340_vp_relative(now, sms_vp); > case 0x2: > - return gsm340_vp_relative_integer(sms_vp); > + return gsm340_vp_relative_integer(now, sms_vp); > case 0x3: > - return gsm340_vp_relative_semioctet(sms_vp); > + return gsm340_vp_relative_semioctet(now, sms_vp); > default: > /* The GSM spec says that the SC should reject any > unsupported and/or undefined values. FIXME */ > LOGP(DLSMS, LOGL_ERROR, > "Reserved enhanced validity period format\n"); > - return gsm340_vp_default(); > + return gsm340_vp_default(now); > } > case GSM340_TP_VPF_NONE: > default: > - return gsm340_vp_default(); > + return gsm340_vp_default(now); > } > } > > -- > 1.7.9.5 > Regards, Daniel -- - 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 alexander.chemeris at gmail.com Tue Mar 11 20:44:24 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 00:44:24 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: <20140311192602.GE27543@adrastea.totalueberwachung.de> References: <20140311192602.GE27543@adrastea.totalueberwachung.de> Message-ID: Hi Daniel, On Tue, Mar 11, 2014 at 11:26 PM, Daniel Willmann wrote: > On Fri, 2014-03-07 at 20:11, Alexander Chemeris wrote: >> -unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp) >> +time_t gsm340_validity_period(time_t now, uint8_t sms_vpf, uint8_t *sms_vp) >> { >> uint8_t fi; /* functionality indicator */ >> >> switch (sms_vpf) { >> case GSM340_TP_VPF_RELATIVE: >> - return gsm340_vp_relative(sms_vp); >> + return gsm340_vp_relative(now, sms_vp); > > You could also omit now in all the static function and return now + > func() in gsm340_validity_period(). > That looks slightly cleaner to me and shouldn't change testability. I made it this way to follow a principle of least surprise - you know, that you always get absolute time as a return value and you don't even need to think about this. But that said, this is a minor issue to me, so I've changed it. All other comments are proper and are also fixed in the attached patch and in the branch (achemeris/sms-validity). -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Proper-decoding-and-storage-of-SMS-validity-peri.patch Type: text/x-patch Size: 6947 bytes Desc: not available URL: From alexander.chemeris at gmail.com Tue Mar 11 21:44:12 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 01:44:12 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> Message-ID: I've updated the patch to rename gsm340_validity_period() to gsm340_validity_period_2() and keep gsm340_validity_period() as a deprecated broken implementation. This way we keep compatibility with older OpenBSC versions without updating to a new libosmocore library. Branch achemeris/sms-validity is updated accordingly. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Proper-decoding-and-storage-of-SMS-validity-peri.patch Type: text/x-patch Size: 7986 bytes Desc: not available URL: From dwillmann at sysmocom.de Wed Mar 12 14:59:51 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 12 Mar 2014 15:59:51 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> Message-ID: <20140312145951.GA2371@adrastea.totalueberwachung.de> Hello Alexander, On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote: > I've updated the patch to rename gsm340_validity_period() to > gsm340_validity_period_2() and keep gsm340_validity_period() as a > deprecated broken implementation. This way we keep compatibility with > older OpenBSC versions without updating to a new libosmocore library. looks all fine except for the function name. Something more expressive would be nice - how about gsm340_validity_period_as_ts()? Regards, Daniel From alexander.chemeris at gmail.com Wed Mar 12 15:53:00 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 19:53:00 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: <20140312145951.GA2371@adrastea.totalueberwachung.de> References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> Message-ID: On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann wrote: > Hello Alexander, > > On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote: >> I've updated the patch to rename gsm340_validity_period() to >> gsm340_validity_period_2() and keep gsm340_validity_period() as a >> deprecated broken implementation. This way we keep compatibility with >> older OpenBSC versions without updating to a new libosmocore library. > > looks all fine except for the function name. Something more expressive > would be nice - how about gsm340_validity_period_as_ts()? I'm not sure "as_ts" is really more expressive, gsm340_validity_period_unix_time() would be more expressive, but it's also painfully long. I would suggest: - gsm340_validity_time() - gsm340_validity_period_decode() - leave as is -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Wed Mar 12 15:55:55 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 19:55:55 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> Message-ID: On Wed, Mar 12, 2014 at 7:53 PM, Alexander Chemeris wrote: > On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann wrote: >> Hello Alexander, >> >> On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote: >>> I've updated the patch to rename gsm340_validity_period() to >>> gsm340_validity_period_2() and keep gsm340_validity_period() as a >>> deprecated broken implementation. This way we keep compatibility with >>> older OpenBSC versions without updating to a new libosmocore library. >> >> looks all fine except for the function name. Something more expressive >> would be nice - how about gsm340_validity_period_as_ts()? > > I'm not sure "as_ts" is really more expressive, > gsm340_validity_period_unix_time() would be more expressive, but it's > also painfully long. I would suggest: > - gsm340_validity_time() > - gsm340_validity_period_decode() > - leave as is - gsm340_valid_until() -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From dwillmann at sysmocom.de Wed Mar 12 16:02:08 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 12 Mar 2014 17:02:08 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> Message-ID: <20140312160208.GB2371@adrastea.totalueberwachung.de> On Wed, 2014-03-12 at 19:53, Alexander Chemeris wrote: > On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann wrote: > > looks all fine except for the function name. Something more expressive > > would be nice - how about gsm340_validity_period_as_ts()? > > I'm not sure "as_ts" is really more expressive, > gsm340_validity_period_unix_time() would be more expressive, but it's > also painfully long. I would suggest: > - gsm340_validity_time() I like that one. Regards, -- - 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 alexander.chemeris at gmail.com Wed Mar 12 17:06:29 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 21:06:29 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: <20140312160208.GB2371@adrastea.totalueberwachung.de> References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> <20140312160208.GB2371@adrastea.totalueberwachung.de> Message-ID: On Wed, Mar 12, 2014 at 8:02 PM, Daniel Willmann wrote: > On Wed, 2014-03-12 at 19:53, Alexander Chemeris wrote: >> On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann wrote: >> > looks all fine except for the function name. Something more expressive >> > would be nice - how about gsm340_validity_period_as_ts()? >> >> I'm not sure "as_ts" is really more expressive, > >> gsm340_validity_period_unix_time() would be more expressive, but it's >> also painfully long. I would suggest: >> - gsm340_validity_time() > > I like that one. Updated -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Proper-decoding-and-storage-of-SMS-validity-peri.patch Type: text/x-patch Size: 7966 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:40:58 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:40:58 +0400 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> <20140312160208.GB2371@adrastea.totalueberwachung.de> Message-ID: Hi Holger, it seems there are no more comments on this code. Could you please merge it? It is independent of other changes. On Wed, Mar 12, 2014 at 9:06 PM, Alexander Chemeris wrote: > On Wed, Mar 12, 2014 at 8:02 PM, Daniel Willmann wrote: >> On Wed, 2014-03-12 at 19:53, Alexander Chemeris wrote: >>> On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann wrote: >>> > looks all fine except for the function name. Something more expressive >>> > would be nice - how about gsm340_validity_period_as_ts()? >>> >>> I'm not sure "as_ts" is really more expressive, >> >>> gsm340_validity_period_unix_time() would be more expressive, but it's >>> also painfully long. I would suggest: >>> - gsm340_validity_time() >> >> I like that one. > > Updated > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From holger at freyther.de Sun Mar 16 09:55:00 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 16 Mar 2014 10:55:00 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> <20140312160208.GB2371@adrastea.totalueberwachung.de> Message-ID: <20140316095500.GH27189@xiaoyu.lan> On Sun, Mar 16, 2014 at 01:40:58PM +0400, Alexander Chemeris wrote: Dear Alexander, > it seems there are no more comments on this code. Could you please merge it? > It is independent of other changes. there is a fixed amount of time I can spend on review a week. You sadly have used some of this time by sending not compiling patches, wrong ones, etc. This means you will need to wait for my next timeslot. The lack of comments doesn't mean that there will be none. E.g. in one of the testcases I noticed that you don't use C99 initializers but the old/error prone way of initializing. :) holger PS: I will not reply the same to all your other messages. ;) From holger at freyther.de Thu Mar 20 21:20:33 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 22:20:33 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> <20140312160208.GB2371@adrastea.totalueberwachung.de> Message-ID: <20140320212033.GA6455@xiaoyu.lan> On Wed, Mar 12, 2014 at 09:06:29PM +0400, Alexander Chemeris wrote: > +/* Decode validity period format 'relative in integer representation'. > + * Returns number of seconds relative to a current time. */ this style of comments is only for net/* in the kernel coding style. > +static time_t gsm340_vp_relative_integer(uint8_t *sms_vp) > { > uint8_t vp; > - unsigned long minutes; > vp = *(sms_vp); > if (vp == 0) { > LOGP(DLSMS, LOGL_ERROR, > "reserved relative_integer validity period\n"); > - return gsm340_vp_default(); > +#warning We should return an RP-Error here. > + return SMS_DEFAULT_VALIDITY_PERIOD; What does this warning mean? The code will not be able to generate and initiate the RP-Error procedure. So how do you intend to indicate the error condition? What should the caler do? From dwillmann at sysmocom.de Wed Mar 26 14:14:03 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 15:14:03 +0100 Subject: [PATCH] sms: Proper decoding and storage of SMS validity period. In-Reply-To: <20140320212033.GA6455@xiaoyu.lan> References: <20140311192602.GE27543@adrastea.totalueberwachung.de> <20140312145951.GA2371@adrastea.totalueberwachung.de> <20140312160208.GB2371@adrastea.totalueberwachung.de> <20140320212033.GA6455@xiaoyu.lan> Message-ID: <20140326141403.GA14692@adrastea.totalueberwachung.de> Hi Holger, On Thu, 2014-03-20 at 22:20, Holger Hans Peter Freyther wrote: > On Wed, Mar 12, 2014 at 09:06:29PM +0400, Alexander Chemeris wrote: > > > +static time_t gsm340_vp_relative_integer(uint8_t *sms_vp) > > { > > uint8_t vp; > > - unsigned long minutes; > > vp = *(sms_vp); > > if (vp == 0) { > > LOGP(DLSMS, LOGL_ERROR, > > "reserved relative_integer validity period\n"); > > - return gsm340_vp_default(); > > +#warning We should return an RP-Error here. > > + return SMS_DEFAULT_VALIDITY_PERIOD; > > What does this warning mean? The code will not be able to generate > and initiate the RP-Error procedure. So how do you intend to indicate > the error condition? What should the caler do? The GSM spec wants us to send back an RP-Error in this case as well as in the default: of gsm340_validity_period(). The latter already has a FIXME comment in it and I just wanted to make sure we don't forget this case if we implement the rp-error. That's why I asked that we either put a FIXME or #warning here. I think we can signal an error condition by returning 0 (both in gsm340_vp_relative_integer() and in gsm340_validity_time() and the caller of gsm340_validity_time() can then deal with the error and return a proper RP-Error in the future. Thinking about it I guess we should implement it like that right now. Regards, Daniel -- - 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 alexander.chemeris at gmail.com Fri Mar 7 20:15:51 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 21:15:51 +0100 Subject: [PATCH 2/6] sms_test: Do not crash on logging. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-sms_test-Do-not-crash-on-logging.patch Type: text/x-patch Size: 964 bytes Desc: not available URL: From dwillmann at sysmocom.de Wed Mar 12 16:09:42 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 12 Mar 2014 17:09:42 +0100 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: References: Message-ID: <20140312160942.GC2371@adrastea.totalueberwachung.de> Hello Alexander, On Fri, 2014-03-07 at 21:15, Alexander Chemeris wrote: > From 13d7321d553b920b4b66d4c7d8f6f20c82bc3459 Mon Sep 17 00:00:00 2001 > From: Alexander Chemeris > Date: Fri, 7 Mar 2014 20:42:03 +0100 > Subject: [PATCH 2/6] sms_test: Do not crash on logging. > > --- > tests/sms/sms_test.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c > index 755b321..cd21e92 100644 > --- a/tests/sms/sms_test.c > +++ b/tests/sms/sms_test.c > @@ -31,6 +31,10 @@ > #include > #include > > +#include > + > +struct log_info fake_log_info = {}; > + > struct test_case { > const uint8_t *input; > const uint16_t input_length; > @@ -278,6 +282,9 @@ int main(int argc, char** argv) > int nchars; > char result[256]; > > + /* Fake logging. */ > + osmo_init_logging(&fake_log_info); osmo_init_logging() is declared in include/osmocom/core/application.h Regards, Daniel -- - 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 alexander.chemeris at gmail.com Wed Mar 12 16:49:52 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 20:49:52 +0400 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: <20140312160942.GC2371@adrastea.totalueberwachung.de> References: <20140312160942.GC2371@adrastea.totalueberwachung.de> Message-ID: On Wed, Mar 12, 2014 at 8:09 PM, Daniel Willmann wrote: > Hello Alexander, > > On Fri, 2014-03-07 at 21:15, Alexander Chemeris wrote: >> From 13d7321d553b920b4b66d4c7d8f6f20c82bc3459 Mon Sep 17 00:00:00 2001 >> From: Alexander Chemeris >> Date: Fri, 7 Mar 2014 20:42:03 +0100 >> Subject: [PATCH 2/6] sms_test: Do not crash on logging. >> >> --- >> tests/sms/sms_test.c | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c >> index 755b321..cd21e92 100644 >> --- a/tests/sms/sms_test.c >> +++ b/tests/sms/sms_test.c >> @@ -31,6 +31,10 @@ >> #include >> #include >> >> +#include >> + >> +struct log_info fake_log_info = {}; >> + >> struct test_case { >> const uint8_t *input; >> const uint16_t input_length; >> @@ -278,6 +282,9 @@ int main(int argc, char** argv) >> int nchars; >> char result[256]; >> >> + /* Fake logging. */ >> + osmo_init_logging(&fake_log_info); > > osmo_init_logging() is declared in include/osmocom/core/application.h Fixed, thanks. I don't like this fact that in C it's possible to use a non-defined function and it's just a warning. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-sms_test-Do-not-crash-on-logging.patch Type: text/x-patch Size: 1012 bytes Desc: not available URL: From noselasd at fiane.dyndns.org Wed Mar 12 18:17:31 2014 From: noselasd at fiane.dyndns.org (noselasd at fiane.dyndns.org) Date: Wed, 12 Mar 2014 19:17:31 +0100 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: References: <20140312160942.GC2371@adrastea.totalueberwachung.de> Message-ID: <5320A4BB.5030608@fiane.dyndns.org> On 03/12/2014 05:49 PM, Alexander Chemeris wrote: >>> +#include >>> + >>> +struct log_info fake_log_info = {}; >>> + >>> struct test_case { >>> const uint8_t *input; >>> const uint16_t input_length; >>> @@ -278,6 +282,9 @@ int main(int argc, char** argv) >>> int nchars; >>> char result[256]; >>> >>> + /* Fake logging. */ >>> + osmo_init_logging(&fake_log_info); >> >> osmo_init_logging() is declared in include/osmocom/core/application.h > > Fixed, thanks. > > I don't like this fact that in C it's possible to use a non-defined > function and it's just a warning. gcc and clang can error on it with the flag -Werror=implicit-function-declaration From alexander.chemeris at gmail.com Wed Mar 12 18:27:09 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 22:27:09 +0400 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: <5320A4BB.5030608@fiane.dyndns.org> References: <20140312160942.GC2371@adrastea.totalueberwachung.de> <5320A4BB.5030608@fiane.dyndns.org> Message-ID: 12 ????? 2014 ?. 22:18 ???????????? ???????: > > On 03/12/2014 05:49 PM, Alexander Chemeris wrote: > >>>> +#include >>>> + >>>> +struct log_info fake_log_info = {}; >>>> + >>>> struct test_case { >>>> const uint8_t *input; >>>> const uint16_t input_length; >>>> @@ -278,6 +282,9 @@ int main(int argc, char** argv) >>>> int nchars; >>>> char result[256]; >>>> >>>> + /* Fake logging. */ >>>> + osmo_init_logging(&fake_log_info); >>> >>> >>> osmo_init_logging() is declared in include/osmocom/core/application.h >> >> >> Fixed, thanks. >> >> I don't like this fact that in C it's possible to use a non-defined >> function and it's just a warning. > > > gcc and clang can error on it with the flag > -Werror=implicit-function-declaration Should we add this to our default Makefiles? Any opinions? Please excuse typos. Written with a touchscreen keyboard. -- Regards, Alexander Chemeris CEO/Founder Fairwaves LLC https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Wed Mar 12 20:44:17 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 12 Mar 2014 21:44:17 +0100 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: References: <20140312160942.GC2371@adrastea.totalueberwachung.de> Message-ID: <20140312204417.GJ2164@xiaoyu.lan> On Wed, Mar 12, 2014 at 08:49:52PM +0400, Alexander Chemeris wrote: > +#include > +#include include/osmocom/core?? From alexander.chemeris at gmail.com Thu Mar 13 08:18:49 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 13 Mar 2014 12:18:49 +0400 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: <20140312204417.GJ2164@xiaoyu.lan> References: <20140312160942.GC2371@adrastea.totalueberwachung.de> <20140312204417.GJ2164@xiaoyu.lan> Message-ID: On Thu, Mar 13, 2014 at 12:44 AM, Holger Hans Peter Freyther wrote: > On Wed, Mar 12, 2014 at 08:49:52PM +0400, Alexander Chemeris wrote: > >> +#include >> +#include > > include/osmocom/core?? Hum, indeed. I have to update my mind model on what leads to compile errors and what is not. An updated patch is attached. Please merge it if there are no more comments. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-sms_test-Do-not-crash-on-logging.patch Type: text/x-patch Size: 1004 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:41:56 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:41:56 +0400 Subject: [PATCH 2/6] sms_test: Do not crash on logging. In-Reply-To: References: <20140312160942.GC2371@adrastea.totalueberwachung.de> <20140312204417.GJ2164@xiaoyu.lan> Message-ID: Hi Holger, It seems there are no more comments on this code. Could you please merge it? It is independent of other changes. On Thu, Mar 13, 2014 at 12:18 PM, Alexander Chemeris wrote: > On Thu, Mar 13, 2014 at 12:44 AM, Holger Hans Peter Freyther > wrote: >> On Wed, Mar 12, 2014 at 08:49:52PM +0400, Alexander Chemeris wrote: >> >>> +#include >>> +#include >> >> include/osmocom/core?? > > Hum, indeed. I have to update my mind model on what leads to compile > errors and what is not. > > An updated patch is attached. Please merge it if there are no more comments. > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Fri Mar 7 20:17:19 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 21:17:19 +0100 Subject: [PATCH 3/6] sms_test: Introduce tests for SMS Vvalidity time relative and absolute formats. Message-ID: This tests demonstrate issues with the current code. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-sms_test-Introduce-tests-for-SMS-Vvalidity-time-rela.patch Type: text/x-patch Size: 6231 bytes Desc: not available URL: From alexander.chemeris at gmail.com Fri Mar 7 23:45:29 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 00:45:29 +0100 Subject: [PATCH 3/6] sms_test: Introduce tests for SMS Vvalidity time relative and absolute formats. In-Reply-To: References: Message-ID: On Fri, Mar 7, 2014 at 9:17 PM, Alexander Chemeris < alexander.chemeris at gmail.com> wrote: > This tests demonstrate issues with the current code. > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-sms_test-Introduce-tests-for-SMS-Validity-time-relat.patch Type: text/x-patch Size: 5505 bytes Desc: not available URL: From alexander.chemeris at gmail.com Wed Mar 12 17:08:00 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 21:08:00 +0400 Subject: [PATCH 3/6] sms_test: Introduce tests for SMS Vvalidity time relative and absolute formats. In-Reply-To: References: Message-ID: Updated after the gsm340_validity_time() rename. On Sat, Mar 8, 2014 at 3:45 AM, Alexander Chemeris wrote: > > > > On Fri, Mar 7, 2014 at 9:17 PM, Alexander Chemeris > wrote: >> >> This tests demonstrate issues with the current code. >> >> -- >> Regards, >> Alexander Chemeris. >> CEO, Fairwaves, Inc. / ??? ??????? >> https://fairwaves.co > > > > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-sms_test-Introduce-tests-for-SMS-Validity-time-relat.patch Type: text/x-patch Size: 9893 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:44:04 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:44:04 +0400 Subject: [PATCH 3/6] sms_test: Introduce tests for SMS Vvalidity time relative and absolute formats. In-Reply-To: References: Message-ID: Hi Holger, It seems there are no comments on this code. Could you please merge it? It is independent of other changes, though it will break "make check" until all other patches are merged. On Wed, Mar 12, 2014 at 9:08 PM, Alexander Chemeris wrote: > Updated after the gsm340_validity_time() rename. > > On Sat, Mar 8, 2014 at 3:45 AM, Alexander Chemeris > wrote: >> >> >> >> On Fri, Mar 7, 2014 at 9:17 PM, Alexander Chemeris >> wrote: >>> >>> This tests demonstrate issues with the current code. >>> >>> -- >>> Regards, >>> Alexander Chemeris. >>> CEO, Fairwaves, Inc. / ??? ??????? >>> https://fairwaves.co >> >> >> >> >> -- >> Regards, >> Alexander Chemeris. >> CEO, Fairwaves, Inc. / ??? ??????? >> https://fairwaves.co > > > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Fri Mar 7 20:17:53 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 21:17:53 +0100 Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time calculation. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-sms-Add-missing-brackets-in-the-relative-validity-ti.patch Type: text/x-patch Size: 1006 bytes Desc: not available URL: From dwillmann at sysmocom.de Tue Mar 11 19:28:18 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Tue, 11 Mar 2014 20:28:18 +0100 Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time calculation. In-Reply-To: References: Message-ID: <20140311192817.GF27543@adrastea.totalueberwachung.de> Looks good, thanks. On Fri, 2014-03-07 at 21:17, Alexander Chemeris wrote: > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co > From c73e793eda7b0961f83956fd4ed2aac378a0869e Mon Sep 17 00:00:00 2001 > From: Alexander Chemeris > Date: Fri, 7 Mar 2014 21:00:19 +0100 > Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time > calculation. > > --- > src/gsm/gsm0411_utils.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c > index 1a6862b..6272ba3 100644 > --- a/src/gsm/gsm0411_utils.c > +++ b/src/gsm/gsm0411_utils.c > @@ -137,13 +137,13 @@ static unsigned long gsm340_vp_relative(time_t now, uint8_t *sms_vp) > > vp = *(sms_vp); > if (vp <= 143) > - minutes = vp + 1 * 5; > + minutes = (vp + 1) * 5; > else if (vp <= 167) > minutes = 12*60 + (vp-143) * 30; > else if (vp <= 196) > - minutes = vp-166 * 60 * 24; > + minutes = (vp-166) * 60 * 24; > else > - minutes = vp-192 * 60 * 24 * 7; > + minutes = (vp-192) * 60 * 24 * 7; > > /* Calculate absolute time from the relative offset */ > return now + minutes * 60; > -- > 1.7.9.5 > -- - 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 alexander.chemeris at gmail.com Tue Mar 11 20:22:04 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 00:22:04 +0400 Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time calculation. In-Reply-To: <20140311192817.GF27543@adrastea.totalueberwachung.de> References: <20140311192817.GF27543@adrastea.totalueberwachung.de> Message-ID: Thanks. Looking forward to your review of other 4 patches :) On Tue, Mar 11, 2014 at 11:28 PM, Daniel Willmann wrote: > Looks good, thanks. > > On Fri, 2014-03-07 at 21:17, Alexander Chemeris wrote: >> -- >> Regards, >> Alexander Chemeris. >> CEO, Fairwaves, Inc. / ??? ??????? >> https://fairwaves.co > >> From c73e793eda7b0961f83956fd4ed2aac378a0869e Mon Sep 17 00:00:00 2001 >> From: Alexander Chemeris >> Date: Fri, 7 Mar 2014 21:00:19 +0100 >> Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time >> calculation. >> >> --- >> src/gsm/gsm0411_utils.c | 6 +++--- >> 1 file changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c >> index 1a6862b..6272ba3 100644 >> --- a/src/gsm/gsm0411_utils.c >> +++ b/src/gsm/gsm0411_utils.c >> @@ -137,13 +137,13 @@ static unsigned long gsm340_vp_relative(time_t now, uint8_t *sms_vp) >> >> vp = *(sms_vp); >> if (vp <= 143) >> - minutes = vp + 1 * 5; >> + minutes = (vp + 1) * 5; >> else if (vp <= 167) >> minutes = 12*60 + (vp-143) * 30; >> else if (vp <= 196) >> - minutes = vp-166 * 60 * 24; >> + minutes = (vp-166) * 60 * 24; >> else >> - minutes = vp-192 * 60 * 24 * 7; >> + minutes = (vp-192) * 60 * 24 * 7; >> >> /* Calculate absolute time from the relative offset */ >> return now + minutes * 60; >> -- >> 1.7.9.5 >> > > > -- > - 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 -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Sun Mar 16 09:44:32 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:44:32 +0400 Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time calculation. In-Reply-To: References: <20140311192817.GF27543@adrastea.totalueberwachung.de> Message-ID: Hi Holger, It seems there are no more comments on this code. Could you please merge it? It is independent of other changes. On Wed, Mar 12, 2014 at 12:22 AM, Alexander Chemeris wrote: > Thanks. > Looking forward to your review of other 4 patches :) > > On Tue, Mar 11, 2014 at 11:28 PM, Daniel Willmann wrote: >> Looks good, thanks. >> >> On Fri, 2014-03-07 at 21:17, Alexander Chemeris wrote: >>> -- >>> Regards, >>> Alexander Chemeris. >>> CEO, Fairwaves, Inc. / ??? ??????? >>> https://fairwaves.co >> >>> From c73e793eda7b0961f83956fd4ed2aac378a0869e Mon Sep 17 00:00:00 2001 >>> From: Alexander Chemeris >>> Date: Fri, 7 Mar 2014 21:00:19 +0100 >>> Subject: [PATCH 4/6] sms: Add missing brackets in the relative validity time >>> calculation. >>> >>> --- >>> src/gsm/gsm0411_utils.c | 6 +++--- >>> 1 file changed, 3 insertions(+), 3 deletions(-) >>> >>> diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c >>> index 1a6862b..6272ba3 100644 >>> --- a/src/gsm/gsm0411_utils.c >>> +++ b/src/gsm/gsm0411_utils.c >>> @@ -137,13 +137,13 @@ static unsigned long gsm340_vp_relative(time_t now, uint8_t *sms_vp) >>> >>> vp = *(sms_vp); >>> if (vp <= 143) >>> - minutes = vp + 1 * 5; >>> + minutes = (vp + 1) * 5; >>> else if (vp <= 167) >>> minutes = 12*60 + (vp-143) * 30; >>> else if (vp <= 196) >>> - minutes = vp-166 * 60 * 24; >>> + minutes = (vp-166) * 60 * 24; >>> else >>> - minutes = vp-192 * 60 * 24 * 7; >>> + minutes = (vp-192) * 60 * 24 * 7; >>> >>> /* Calculate absolute time from the relative offset */ >>> return now + minutes * 60; >>> -- >>> 1.7.9.5 >>> >> >> >> -- >> - 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 > > > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Fri Mar 7 20:24:40 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 21:24:40 +0100 Subject: [PATCH 5/6] sms: Fix support of negative timezone offsets in gsm340_gen_scts(). Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-sms-Fix-support-of-negative-timezone-offsets-in-gsm3.patch Type: text/x-patch Size: 958 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:35:49 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:35:49 +0400 Subject: [PATCH 5/6] sms: Fix support of negative timezone offsets in gsm340_gen_scts(). In-Reply-To: References: Message-ID: Hi Daniel, Could you please review this patch? It is the last one from the achemeris/sms-validity series and is the smallest one. On Sat, Mar 8, 2014 at 12:24 AM, Alexander Chemeris wrote: > > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From dwillmann at sysmocom.de Thu Mar 20 21:33:08 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Thu, 20 Mar 2014 22:33:08 +0100 Subject: [PATCH 5/6] sms: Fix support of negative timezone offsets in gsm340_gen_scts(). In-Reply-To: References: Message-ID: <20140320213308.GA18845@adrastea.totalueberwachung.de> Hi Alexander, On Sun, 2014-03-16 at 13:35, Alexander Chemeris wrote: > Could you please review this patch? It is the last one from the > achemeris/sms-validity series and is the smallest one. this patch looks fine. Regards, Daniel -- - 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 dwillmann at sysmocom.de Wed Mar 26 16:57:40 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 17:57:40 +0100 Subject: [PATCH 5/6] sms: Fix support of negative timezone offsets in gsm340_gen_scts(). In-Reply-To: References: Message-ID: <20140326165740.GB14692@adrastea.totalueberwachung.de> Dear Alexander, On Fri, 2014-03-07 at 21:24, Alexander Chemeris wrote: > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co > From 44600bbe8d0de88b7fbb2530e12b9122bf6e52df Mon Sep 17 00:00:00 2001 > From: Alexander Chemeris > Date: Fri, 7 Mar 2014 21:02:46 +0100 > Subject: [PATCH 5/6] sms: Fix support of negative timezone offsets in > gsm340_gen_scts(). > > --- > src/gsm/gsm0411_utils.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c > index 6272ba3..e884eca 100644 > --- a/src/gsm/gsm0411_utils.c > +++ b/src/gsm/gsm0411_utils.c > @@ -85,7 +85,10 @@ void gsm340_gen_scts(uint8_t *scts, time_t time) > *scts++ = gsm411_bcdify(tm->tm_min); > *scts++ = gsm411_bcdify(tm->tm_sec); > #ifdef HAVE_TM_GMTOFF_IN_TM > - *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15)); > + if (tm->tm_gmtoff >= 0) > + *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15)); > + else > + *scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x80; > #else > #warning find a portable way to obtain timezone offset > *scts++ = 0; > -- > 1.7.9.5 after looking through the code and thinking about mktime/timegm some more I noticed that we actually want to used localtime() instead of gmtime() in this function. gmtime will always set tm_gmtoff zero (as it converts it into UTC). This function could be written without any use of tm_gmtoff by using both localtime and gmtime, converting these results back to time_t with mktime and calculating the difference. I'll send a patch in a an extra mail. Regards, Daniel -- - 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 dwillmann at sysmocom.de Wed Mar 26 17:36:54 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 18:36:54 +0100 Subject: [RFC 1/1] gsm0411_utils: Fix timezone offs calculation in gsm340_gen_scts() In-Reply-To: <20140326165740.GB14692@adrastea.totalueberwachung.de> References: <20140326165740.GB14692@adrastea.totalueberwachung.de> Message-ID: The current code uses gmtime which returns the time in UTC. This is not the intended behaviour (otherwise the offset could always be set to zero). This uses localtime as well as gmtime to calculate the timezone offset instead of relying on tm_gmtoff. This means three extra function calls (mktime * 2, gmtime_r), but this is completely independent of non-standard features. --- src/gsm/gsm0411_utils.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index bb59a10..18664dc 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -77,23 +77,32 @@ uint8_t gsm411_unbcdify(uint8_t value) /* Generate 03.40 TP-SCTS */ void gsm340_gen_scts(uint8_t *scts, time_t time) { - struct tm *tm = gmtime(&time); - - *scts++ = gsm411_bcdify(tm->tm_year % 100); - *scts++ = gsm411_bcdify(tm->tm_mon + 1); - *scts++ = gsm411_bcdify(tm->tm_mday); - *scts++ = gsm411_bcdify(tm->tm_hour); - *scts++ = gsm411_bcdify(tm->tm_min); - *scts++ = gsm411_bcdify(tm->tm_sec); -#ifdef HAVE_TM_GMTOFF_IN_TM - if (tm->tm_gmtoff >= 0) - *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15)); + struct tm tm_local, tm_utc; + time_t ts_local, ts_utc, gmtoffset; + + localtime_r(&time, &tm_local); + + *scts++ = gsm411_bcdify(tm_local.tm_year % 100); + *scts++ = gsm411_bcdify(tm_local.tm_mon + 1); + *scts++ = gsm411_bcdify(tm_local.tm_mday); + *scts++ = gsm411_bcdify(tm_local.tm_hour); + *scts++ = gsm411_bcdify(tm_local.tm_min); + *scts++ = gsm411_bcdify(tm_local.tm_sec); + + /* Figure out the timezone offset in a portable way. + * The idea is to convert the time_t into local and UTC struct tm + * representations and then calculate the difference of both. */ + gmtime_r(&time, &tm_utc); + tm_utc.is_dst = 0; + tm_local.is_dst = 0; + ts_utc = mktime(&tm_utc); + ts_local = mktime(&tm_local); + gmtoffset = ts_local - ts_utc; + + if (gmtoffset >= 0) + *scts++ = gsm411_bcdify(gmtoffset/(60*15)); else - *scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x80; -#else -#warning find a portable way to obtain timezone offset - *scts++ = 0; -#endif + *scts++ = gsm411_bcdify(-gmtoffset/(60*15)) | 0x80; } /* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */ -- 1.8.4.2 From alexander.chemeris at gmail.com Fri Mar 7 20:25:33 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 7 Mar 2014 21:25:33 +0100 Subject: [PATCH 6/6] sms: Fix gsm340_scts() to correctly decode absolute valid times. Message-ID: - Support negative timezone offsets decoding. - Correctly account timezone offset and artificial offset mktime() introduces. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: From dwillmann at sysmocom.de Wed Mar 12 18:53:13 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 12 Mar 2014 19:53:13 +0100 Subject: [PATCH 6/6] sms: Fix gsm340_scts() to correctly decode absolute valid times. In-Reply-To: References: Message-ID: <20140312185313.GD2371@adrastea.totalueberwachung.de> Hello Alexander, On Fri, 2014-03-07 at 21:25, Alexander Chemeris wrote: > - Support negative timezone offsets decoding. > - Correctly account timezone offset and artificial offset mktime() > introduces. patch seems missing, I included the current one: > From b8ed8ed29d239693e2b32b62cbac3b2847937b9b Mon Sep 17 00:00:00 2001 > Message-Id: > From: Alexander Chemeris > Date: Fri, 7 Mar 2014 21:03:44 +0100 > Subject: [PATCH 1/1] sms: Fix gsm340_scts() to correctly decode absolute valid > times. > > - Support negative timezone offsets decoding. > - Correctly account timezone offset and artificial offset mktime() introduces. > --- > src/gsm/gsm0411_utils.c | 31 +++++++++++++++++++++++-------- > 1 file changed, 23 insertions(+), 8 deletions(-) > > diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c > index bb59a10..e199b6a 100644 > --- a/src/gsm/gsm0411_utils.c > +++ b/src/gsm/gsm0411_utils.c > @@ -100,11 +100,13 @@ void gsm340_gen_scts(uint8_t *scts, time_t time) > time_t gsm340_scts(uint8_t *scts) > { > struct tm tm; > - uint8_t yr = gsm411_unbcdify(*scts++); > - int ofs; > + uint8_t yr, tz; > + int ofs = 0; Do we need to initialize ofs? It looks like both before and now ofs is always assigned before use. > + time_t timestamp; > > memset(&tm, 0x00, sizeof(struct tm)); > > + yr = gsm411_unbcdify(*scts++); > if (yr <= 80) > tm.tm_year = 100 + yr; > else > @@ -114,15 +116,28 @@ time_t gsm340_scts(uint8_t *scts) > tm.tm_hour = gsm411_unbcdify(*scts++); > tm.tm_min = gsm411_unbcdify(*scts++); > tm.tm_sec = gsm411_unbcdify(*scts++); > -#ifdef HAVE_TM_GMTOFF_IN_TM > - tm.tm_gmtoff = gsm411_unbcdify(*scts++) * 15*60; > -#endif By deleting the #ifdef here and not adding it below you'll break cygwin builds. See commit 7c8e2cc7aca1a789bbcf989a14be177d59041959. > /* according to gsm 03.40 time zone is > "expressed in quarters of an hour" */ > - ofs = gsm411_unbcdify(*scts++) * 15*60; > - > - return mktime(&tm) - ofs; > + tz = *scts++; > + ofs = gsm411_unbcdify(tz&0x7f) * 15*60; > + if (tz&0x80) > + ofs = -ofs; > + /* mktime() doesn't tm.tm_gmtoff into account. Instead, it fills this field doesn't take > + * with the current timezone. Which means that the resulting time is off > + * by several hours after that. So here we're setting tm.tm_isdt to -1 > + * to indicate that the tm time is local, but later we subtract the > + * offset introduced by mktime. */ > + tm.tm_isdst = -1; > + > + timestamp = mktime(&tm); > + if (timestamp < 0) > + return -1; > + > + /* Subtract artificial timezone offset, introduced by mktime() */ > + timestamp = timestamp - ofs + tm.tm_gmtoff; > + > + return timestamp; > } > > /* Decode validity period format 'relative'. > -- > 1.8.4.2 I'm still not convinced that we want to use mktime and tm_gmtoff for the calculation. There's timegm() which is the inverse of gmtime() which I think we should use were it's available. Depending on timegm shouldn't make us and more dependent on some extension than we already are with tm_gmtoff. The man page has a note on how to implement a portable version, though it involves calling setenv (to set TZ to UTC) and I'm not sure we want to do that in a library. Additional discussion welcome. Regards, Daniel -- - 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 alexander.chemeris at gmail.com Thu Mar 13 08:37:07 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 13 Mar 2014 12:37:07 +0400 Subject: [PATCH 6/6] sms: Fix gsm340_scts() to correctly decode absolute valid times. In-Reply-To: <20140312185313.GD2371@adrastea.totalueberwachung.de> References: <20140312185313.GD2371@adrastea.totalueberwachung.de> Message-ID: On Wed, Mar 12, 2014 at 10:53 PM, Daniel Willmann wrote: > Hello Alexander, > > On Fri, 2014-03-07 at 21:25, Alexander Chemeris wrote: >> @@ -100,11 +100,13 @@ void gsm340_gen_scts(uint8_t *scts, time_t time) >> time_t gsm340_scts(uint8_t *scts) >> { >> struct tm tm; >> - uint8_t yr = gsm411_unbcdify(*scts++); >> - int ofs; >> + uint8_t yr, tz; >> + int ofs = 0; > > Do we need to initialize ofs? It looks like both before and now ofs is > always assigned before use. Yeah, a leftover from an intermediate implementation I had. Fixed. >> @@ -114,15 +116,28 @@ time_t gsm340_scts(uint8_t *scts) >> tm.tm_hour = gsm411_unbcdify(*scts++); >> tm.tm_min = gsm411_unbcdify(*scts++); >> tm.tm_sec = gsm411_unbcdify(*scts++); >> -#ifdef HAVE_TM_GMTOFF_IN_TM >> - tm.tm_gmtoff = gsm411_unbcdify(*scts++) * 15*60; >> -#endif > > By deleting the #ifdef here and not adding it below you'll break cygwin > builds. See commit 7c8e2cc7aca1a789bbcf989a14be177d59041959. Fixed. >> /* according to gsm 03.40 time zone is >> "expressed in quarters of an hour" */ >> - ofs = gsm411_unbcdify(*scts++) * 15*60; >> - >> - return mktime(&tm) - ofs; >> + tz = *scts++; >> + ofs = gsm411_unbcdify(tz&0x7f) * 15*60; >> + if (tz&0x80) >> + ofs = -ofs; >> + /* mktime() doesn't tm.tm_gmtoff into account. Instead, it fills this field > doesn't take Thanks. >> + * with the current timezone. Which means that the resulting time is off >> + * by several hours after that. So here we're setting tm.tm_isdt to -1 >> + * to indicate that the tm time is local, but later we subtract the >> + * offset introduced by mktime. */ >> + tm.tm_isdst = -1; >> + >> + timestamp = mktime(&tm); >> + if (timestamp < 0) >> + return -1; >> + >> + /* Subtract artificial timezone offset, introduced by mktime() */ >> + timestamp = timestamp - ofs + tm.tm_gmtoff; >> + >> + return timestamp; >> } >> >> /* Decode validity period format 'relative'. >> -- >> 1.8.4.2 > > I'm still not convinced that we want to use mktime and tm_gmtoff for the > calculation. There's timegm() which is the inverse of gmtime() which I > think we should use were it's available. Depending on timegm shouldn't > make us and more dependent on some extension than we already are with > tm_gmtoff. > > The man page has a note on how to implement a portable version, though > it involves calling setenv (to set TZ to UTC) and I'm not sure we want > to do that in a library. > > Additional discussion welcome. I spent some time thinking about the best solution and came to conclusion that the one with mktime() is the best one. gmtime() is a non-standard extension, so we'll have to detect it, add #ifdef's and then we still will need a code which works if it is not available. And that code will be based on mktime(). So why not to use mktime() from the very beginning? The code is covered with tests, so we will notice any breakage if it occurs on other platforms. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-sms-Fix-gsm340_scts-to-correctly-decode-absolute-val.patch Type: text/x-patch Size: 2208 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:46:48 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:46:48 +0400 Subject: [PATCH 6/6] sms: Fix gsm340_scts() to correctly decode absolute valid times. In-Reply-To: References: <20140312185313.GD2371@adrastea.totalueberwachung.de> Message-ID: Hi Holger, It seems there are no more comments on this code. Could you please merge it? It is independent of other changes. On Thu, Mar 13, 2014 at 12:37 PM, Alexander Chemeris wrote: > On Wed, Mar 12, 2014 at 10:53 PM, Daniel Willmann wrote: >> Hello Alexander, >> >> On Fri, 2014-03-07 at 21:25, Alexander Chemeris wrote: >>> @@ -100,11 +100,13 @@ void gsm340_gen_scts(uint8_t *scts, time_t time) >>> time_t gsm340_scts(uint8_t *scts) >>> { >>> struct tm tm; >>> - uint8_t yr = gsm411_unbcdify(*scts++); >>> - int ofs; >>> + uint8_t yr, tz; >>> + int ofs = 0; >> >> Do we need to initialize ofs? It looks like both before and now ofs is >> always assigned before use. > > Yeah, a leftover from an intermediate implementation I had. Fixed. > >>> @@ -114,15 +116,28 @@ time_t gsm340_scts(uint8_t *scts) >>> tm.tm_hour = gsm411_unbcdify(*scts++); >>> tm.tm_min = gsm411_unbcdify(*scts++); >>> tm.tm_sec = gsm411_unbcdify(*scts++); >>> -#ifdef HAVE_TM_GMTOFF_IN_TM >>> - tm.tm_gmtoff = gsm411_unbcdify(*scts++) * 15*60; >>> -#endif >> >> By deleting the #ifdef here and not adding it below you'll break cygwin >> builds. See commit 7c8e2cc7aca1a789bbcf989a14be177d59041959. > > Fixed. > >>> /* according to gsm 03.40 time zone is >>> "expressed in quarters of an hour" */ >>> - ofs = gsm411_unbcdify(*scts++) * 15*60; >>> - >>> - return mktime(&tm) - ofs; >>> + tz = *scts++; >>> + ofs = gsm411_unbcdify(tz&0x7f) * 15*60; >>> + if (tz&0x80) >>> + ofs = -ofs; >>> + /* mktime() doesn't tm.tm_gmtoff into account. Instead, it fills this field >> doesn't take > > Thanks. > >>> + * with the current timezone. Which means that the resulting time is off >>> + * by several hours after that. So here we're setting tm.tm_isdt to -1 >>> + * to indicate that the tm time is local, but later we subtract the >>> + * offset introduced by mktime. */ >>> + tm.tm_isdst = -1; >>> + >>> + timestamp = mktime(&tm); >>> + if (timestamp < 0) >>> + return -1; >>> + >>> + /* Subtract artificial timezone offset, introduced by mktime() */ >>> + timestamp = timestamp - ofs + tm.tm_gmtoff; >>> + >>> + return timestamp; >>> } >>> >>> /* Decode validity period format 'relative'. >>> -- >>> 1.8.4.2 >> >> I'm still not convinced that we want to use mktime and tm_gmtoff for the >> calculation. There's timegm() which is the inverse of gmtime() which I >> think we should use were it's available. Depending on timegm shouldn't >> make us and more dependent on some extension than we already are with >> tm_gmtoff. >> >> The man page has a note on how to implement a portable version, though >> it involves calling setenv (to set TZ to UTC) and I'm not sure we want >> to do that in a library. >> >> Additional discussion welcome. > > I spent some time thinking about the best solution and came to > conclusion that the one with mktime() is the best one. > > gmtime() is a non-standard extension, so we'll have to detect it, add > #ifdef's and then we still will need a code which works if it is not > available. And that code will be based on mktime(). So why not to use > mktime() from the very beginning? > > The code is covered with tests, so we will notice any breakage if it > occurs on other platforms. > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From dwillmann at sysmocom.de Wed Mar 26 21:44:41 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 22:44:41 +0100 Subject: No subject In-Reply-To: References: Message-ID: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> Dear Alexander, while searching for a portable way to get the gmt offset I have found out that your patches set the wrong semi-octet to de/encode the sign. 3GPP TS 03.40 ch. 9.2.3.11 specifies that "bit 3 of the seventh octet of the TP-Service-Centre-Time-Stamp field [...] represents the algebraic sign of this difference." This is because the more significant digit is encoded in bits 0-3. Currently a two hour time offset (8*15min) will beencoded as 0x80 which will be decoded as -0. Please take a look at my two patches and squash them into yours. [FIX 1/2] fixup! sms: Fix gsm340_scts() to correctly decode absolute [FIX 2/2] fixup! sms: Fix support of negative timezone offsets in Regards, Daniel From dwillmann at sysmocom.de Wed Mar 26 21:44:42 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 22:44:42 +0100 Subject: [FIX 1/2] fixup! sms: Fix gsm340_scts() to correctly decode absolute valid times. In-Reply-To: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> References: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <02248a12c3e51d7e5f8b9ae9e3c54569b706e31a.1395869732.git.daniel@totalueberwachung.de> --- src/gsm/gsm0411_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index 197f2c3..3052dd7 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -120,8 +120,8 @@ time_t gsm340_scts(uint8_t *scts) /* according to gsm 03.40 time zone is "expressed in quarters of an hour" */ tz = *scts++; - ofs = gsm411_unbcdify(tz&0x7f) * 15*60; - if (tz&0x80) + ofs = gsm411_unbcdify(tz&0xf7) * 15*60; + if (tz&0x08) ofs = -ofs; /* mktime() doesn't take tm.tm_gmtoff into account. Instead, it fills this * field with the current timezone. Which means that the resulting time is -- 1.8.4.2 From dwillmann at sysmocom.de Wed Mar 26 21:44:43 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 22:44:43 +0100 Subject: [FIX 2/2] fixup! sms: Fix support of negative timezone offsets in gsm340_gen_scts(). In-Reply-To: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> References: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <0d0003b8fc6be13f400a1407f88b165d3e8af272.1395869732.git.daniel@totalueberwachung.de> --- src/gsm/gsm0411_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index 3052dd7..b8a7b10 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -89,7 +89,7 @@ void gsm340_gen_scts(uint8_t *scts, time_t time) if (tm->tm_gmtoff >= 0) *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15)); else - *scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x80; + *scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x08; #else #warning find a portable way to obtain timezone offset *scts++ = 0; -- 1.8.4.2 From dwillmann at sysmocom.de Wed Mar 26 21:56:30 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 22:56:30 +0100 Subject: your mail In-Reply-To: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> References: <1395870283-30330-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <20140326215630.GA31519@adrastea.totalueberwachung.de> On Wed, 2014-03-26 at 22:44, Daniel Willmann wrote: > Please take a look at my two patches and squash them into yours. Almost forgot: You'll need to update the test as well. Daniel -- - 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 holger at freyther.de Sat Mar 8 12:54:27 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Mar 2014 13:54:27 +0100 Subject: [PATCH 1/4] sms: Kill the sms->sender and use addr/ton/npi throughout the code Message-ID: <1394283270-32229-1-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther This is an incompatible database schema change. Store the type of the address in the database for both the sender and the receiver. Currently it is possible to use SMPP to store a SMS and the NPI and TON will be lost on the delivery of the SMS. The schema is changed to make the delivery always use the right NPI/TON. This patch is not ready for the master branch as there is no upgrade path for the HLR yet. --- openbsc/include/openbsc/gsm_data.h | 1 - openbsc/src/libmsc/db.c | 62 +++++++++++++++++++++++--------------- openbsc/src/libmsc/gsm_04_11.c | 9 ++---- openbsc/src/libmsc/smpp_openbsc.c | 5 ++- 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 1b4720f..e6a94ad 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -304,7 +304,6 @@ struct gsm_sms_addr { struct gsm_sms { unsigned long long id; - struct gsm_subscriber *sender; struct gsm_subscriber *receiver; struct gsm_sms_addr src, dst; enum gsm_sms_source_id source; diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index e26d3c5..39812c1 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -95,7 +95,6 @@ static char *create_stmts[] = { "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "sent TIMESTAMP, " - "sender_id INTEGER NOT NULL, " "receiver_id INTEGER NOT NULL, " "deliver_attempts INTEGER NOT NULL DEFAULT 0, " /* data directly copied/derived from SMS */ @@ -105,7 +104,12 @@ static char *create_stmts[] = { "protocol_id INTEGER NOT NULL, " "data_coding_scheme INTEGER NOT NULL, " "ud_hdr_ind INTEGER NOT NULL, " - "dest_addr TEXT, " + "src_addr TEXT NOT NULL, " + "src_ton INTEGER NOT NULL, " + "src_npi INTEGER NOT NULL, " + "dest_addr TEXT NOT NULL, " + "dest_ton INTEGER NOT NULL, " + "dest_npi INTEGER NOT NULL, " "user_data BLOB, " /* TP-UD */ /* additional data, interpreted from SMS */ "header BLOB, " /* UD Header */ @@ -1094,7 +1098,7 @@ int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char imei[GSM_IM int db_sms_store(struct gsm_sms *sms) { dbi_result result; - char *q_text, *q_daddr; + char *q_text, *q_daddr, *q_saddr; unsigned char *q_udata; char *validity_timestamp = "2222-2-2"; @@ -1102,25 +1106,35 @@ int db_sms_store(struct gsm_sms *sms) dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text); dbi_conn_quote_string_copy(conn, (char *)sms->dst.addr, &q_daddr); + dbi_conn_quote_string_copy(conn, (char *)sms->src.addr, &q_saddr); dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len, &q_udata); + /* FIXME: correct validity period */ result = dbi_conn_queryf(conn, "INSERT INTO SMS " - "(created, sender_id, receiver_id, valid_until, " + "(created, receiver_id, valid_until, " "reply_path_req, status_rep_req, protocol_id, " - "data_coding_scheme, ud_hdr_ind, dest_addr, " - "user_data, text) VALUES " - "(datetime('now'), %llu, %llu, %u, " - "%u, %u, %u, %u, %u, %s, %s, %s)", - sms->sender->id, + "data_coding_scheme, ud_hdr_ind, " + "user_data, text, " + "dest_addr, dest_ton, dest_npi, " + "src_addr, src_ton, src_npi) VALUES " + "(datetime('now'), %llu, %u, " + "%u, %u, %u, " + "%u, %u, " + "%s, %s, " + "%s, %u, %u, " + "%s, %u, %u)", sms->receiver ? sms->receiver->id : 0, validity_timestamp, sms->reply_path_req, sms->status_rep_req, sms->protocol_id, sms->data_coding_scheme, sms->ud_hdr_ind, - q_daddr, q_udata, q_text); + q_udata, q_text, + q_daddr, sms->dst.ton, sms->dst.npi, + q_saddr, sms->src.ton, sms->src.npi); free(q_text); - free(q_daddr); free(q_udata); + free(q_daddr); + free(q_saddr); if (!result) return -EIO; @@ -1132,8 +1146,8 @@ int db_sms_store(struct gsm_sms *sms) static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result) { struct gsm_sms *sms = sms_alloc(); - long long unsigned int sender_id, receiver_id; - const char *text, *daddr; + long long unsigned int receiver_id; + const char *text, *daddr, *saddr; const unsigned char *user_data; if (!sms) @@ -1141,18 +1155,6 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul sms->id = dbi_result_get_ulonglong(result, "id"); - sender_id = dbi_result_get_ulonglong(result, "sender_id"); - sms->sender = subscr_get_by_id(net, sender_id); - if (!sms->sender) { - LOGP(DLSMS, LOGL_ERROR, - "Failed to find sender(%llu) for id(%llu)\n", - sender_id, sms->id); - sms_free(sms); - return NULL; - } - - strncpy(sms->src.addr, sms->sender->extension, sizeof(sms->src.addr)-1); - receiver_id = dbi_result_get_ulonglong(result, "receiver_id"); sms->receiver = subscr_get_by_id(net, receiver_id); if (!sms->receiver) { @@ -1173,12 +1175,22 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul "data_coding_scheme"); /* sms->msg_ref is temporary and not stored in DB */ + sms->dst.npi = dbi_result_get_uint(result, "dest_npi"); + sms->dst.ton = dbi_result_get_uint(result, "dest_ton"); daddr = dbi_result_get_string(result, "dest_addr"); if (daddr) { strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0'; } + sms->src.npi = dbi_result_get_uint(result, "src_npi"); + sms->src.ton = dbi_result_get_uint(result, "src_ton"); + saddr = dbi_result_get_string(result, "src_addr"); + if (saddr) { + strncpy(sms->src.addr, saddr, sizeof(sms->src.addr)); + sms->src.addr[sizeof(sms->src.addr)-1] = '\0'; + } + sms->user_data_len = dbi_result_get_field_length(result, "user_data"); user_data = dbi_result_get_binary(result, "user_data"); if (sms->user_data_len > sizeof(sms->user_data)) diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 975a263..566feb9 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -73,8 +73,6 @@ struct gsm_sms *sms_alloc(void) void sms_free(struct gsm_sms *sms) { /* drop references to subscriber structure */ - if (sms->sender) - subscr_put(sms->sender); if (sms->receiver) subscr_put(sms->receiver); #ifdef BUILD_SMPP @@ -97,8 +95,7 @@ struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, sms->receiver = subscr_get(receiver); strncpy(sms->text, text, sizeof(sms->text)-1); - sms->sender = subscr_get(sender); - strncpy(sms->src.addr, sms->sender->extension, sizeof(sms->src.addr)-1); + strncpy(sms->src.addr, sender->extension, sizeof(sms->src.addr)-1); sms->reply_path_req = 0; sms->status_rep_req = 0; sms->ud_hdr_ind = 0; @@ -378,12 +375,10 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m } } - gsms->sender = subscr_get(conn->subscr); - LOGP(DLSMS, LOGL_INFO, "RX SMS: Sender: %s, MTI: 0x%02x, VPF: 0x%02x, " "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, " "UserDataLength: 0x%02x, UserData: \"%s\"\n", - subscr_name(gsms->sender), sms_mti, sms_vpf, gsms->msg_ref, + subscr_name(conn->subscr), sms_mti, sms_vpf, gsms->msg_ref, gsms->protocol_id, gsms->data_coding_scheme, gsms->dst.addr, gsms->user_data_len, sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text : diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index ab558ce..ec541c2 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -133,7 +133,6 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, strncpy(sms->dst.addr, dest->extension, sizeof(sms->dst.addr)-1); /* fill in the source address */ - sms->sender = subscr_get_by_id(net, 1); sms->src.ton = submit->source_addr_ton; sms->src.npi = submit->source_addr_npi; strncpy(sms->src.addr, (char *)submit->source_addr, sizeof(sms->src.addr)-1); @@ -475,13 +474,13 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, deliver.source_addr_npi = NPI_Land_Mobile_E212; snprintf((char *)deliver.source_addr, sizeof(deliver.source_addr), "%s", - sms->sender->imsi); + conn->subscr->imsi); } else { deliver.source_addr_ton = TON_Network_Specific; deliver.source_addr_npi = NPI_ISDN_E163_E164; snprintf((char *)deliver.source_addr, sizeof(deliver.source_addr), "%s", - sms->sender->extension); + conn->subscr->extension); } deliver.dest_addr_ton = sms->dst.ton; -- 1.9.0 From holger at freyther.de Sat Mar 8 12:54:28 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Mar 2014 13:54:28 +0100 Subject: [PATCH 2/4] db: Add testcase for storing/loading/comparing a sms In-Reply-To: <1394283270-32229-1-git-send-email-holger@freyther.de> References: <1394283270-32229-1-git-send-email-holger@freyther.de> Message-ID: <1394283270-32229-2-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther Use the already created subscriber, create a sms and read it back from the subscriber. --- openbsc/tests/db/db_test.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index 3c5de90..ba3fdfb 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -57,6 +58,64 @@ static struct gsm_network dummy_net; printf("Extensions do not match in %s:%d '%s' '%s'\n", \ __FUNCTION__, __LINE__, original->extension, copy->extension); \ +/* + * Create/Store a SMS and then try to load it. + */ +static void test_sms(void) +{ + int rc; + struct gsm_sms *sms; + struct gsm_subscriber *subscr; + subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445"); + OSMO_ASSERT(subscr); + subscr->net = &dummy_net; + + sms = sms_alloc(); + sms->receiver = subscr_get(subscr); + + sms->src.ton = 0x23; + sms->src.npi = 0x24; + memcpy(sms->src.addr, "1234", strlen("1234") + 1); + + sms->dst.ton = 0x32; + sms->dst.npi = 0x42; + memcpy(sms->dst.addr, subscr->extension, sizeof(subscr->extension)); + + memcpy(sms->text, "Text123", strlen("Text123") + 1); + memcpy(sms->user_data, "UserData123", strlen("UserData123") + 1); + sms->user_data_len = strlen("UserData123"); + + /* random values */ + sms->reply_path_req = 1; + sms->status_rep_req = 2; + sms->ud_hdr_ind = 3; + sms->protocol_id = 4; + sms->data_coding_scheme = 5; + + rc = db_sms_store(sms); + sms_free(sms); + OSMO_ASSERT(rc == 0); + + /* now query */ + sms = db_sms_get_unsent_for_subscr(subscr); + OSMO_ASSERT(sms); + OSMO_ASSERT(sms->receiver == subscr); + OSMO_ASSERT(sms->reply_path_req == 1); + OSMO_ASSERT(sms->status_rep_req == 2); + OSMO_ASSERT(sms->ud_hdr_ind == 3); + OSMO_ASSERT(sms->protocol_id == 4); + OSMO_ASSERT(sms->data_coding_scheme == 5); + OSMO_ASSERT(sms->src.ton == 0x23); + OSMO_ASSERT(sms->src.npi == 0x24); + OSMO_ASSERT(sms->dst.ton == 0x32); + OSMO_ASSERT(sms->dst.npi == 0x42); + OSMO_ASSERT(strcmp((char *) sms->text, "Text123") == 0); + OSMO_ASSERT(sms->user_data_len == strlen("UserData123")); + OSMO_ASSERT(strcmp((char *) sms->user_data, "UserData123") == 0); + + subscr_put(subscr); +} + int main() { printf("Testing subscriber database code.\n"); @@ -108,6 +167,8 @@ int main() SUBSCR_PUT(alice); SUBSCR_PUT(alice_db); + test_sms(); + db_fini(); printf("Done\n"); -- 1.9.0 From holger at freyther.de Sat Mar 8 12:54:29 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Mar 2014 13:54:29 +0100 Subject: [PATCH 3/4] sms: Do not store received id in the SMS database. In-Reply-To: <1394283270-32229-1-git-send-email-holger@freyther.de> References: <1394283270-32229-1-git-send-email-holger@freyther.de> Message-ID: <1394283270-32229-3-git-send-email-holger@freyther.de> From: Alexander Chemeris That was a bad idea from the very beginning. A visible result of this is a wrong SMS routing when you change subscriber extensions, while having queued SMS. It's also a very wrong thing from the code layering perspective. I think the next logical step should be to remove "receiver" pointer from the gsm_sms structure into a structure, special for the internal SMS queue. --- openbsc/src/libmsc/db.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 39812c1..2351485 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -95,7 +95,6 @@ static char *create_stmts[] = { "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "sent TIMESTAMP, " - "receiver_id INTEGER NOT NULL, " "deliver_attempts INTEGER NOT NULL DEFAULT 0, " /* data directly copied/derived from SMS */ "valid_until TIMESTAMP, " @@ -1113,19 +1112,19 @@ int db_sms_store(struct gsm_sms *sms) /* FIXME: correct validity period */ result = dbi_conn_queryf(conn, "INSERT INTO SMS " - "(created, receiver_id, valid_until, " + "(created, valid_until, " "reply_path_req, status_rep_req, protocol_id, " "data_coding_scheme, ud_hdr_ind, " "user_data, text, " "dest_addr, dest_ton, dest_npi, " "src_addr, src_ton, src_npi) VALUES " - "(datetime('now'), %llu, %u, " + "(datetime('now'), %u, " "%u, %u, %u, " "%u, %u, " "%s, %s, " "%s, %u, %u, " "%s, %u, %u)", - sms->receiver ? sms->receiver->id : 0, validity_timestamp, + validity_timestamp, sms->reply_path_req, sms->status_rep_req, sms->protocol_id, sms->data_coding_scheme, sms->ud_hdr_ind, q_udata, q_text, @@ -1146,7 +1145,6 @@ int db_sms_store(struct gsm_sms *sms) static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result) { struct gsm_sms *sms = sms_alloc(); - long long unsigned int receiver_id; const char *text, *daddr, *saddr; const unsigned char *user_data; @@ -1155,16 +1153,6 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul sms->id = dbi_result_get_ulonglong(result, "id"); - receiver_id = dbi_result_get_ulonglong(result, "receiver_id"); - sms->receiver = subscr_get_by_id(net, receiver_id); - if (!sms->receiver) { - LOGP(DLSMS, LOGL_ERROR, - "Failed to find receiver(%llu) for id(%llu)\n", - receiver_id, sms->id); - sms_free(sms); - return NULL; - } - /* FIXME: validity */ /* FIXME: those should all be get_uchar, but sqlite3 is braindead */ sms->reply_path_req = dbi_result_get_uint(result, "reply_path_req"); @@ -1182,6 +1170,7 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0'; } + sms->receiver = subscr_get_by_extension(net, sms->dst.addr); sms->src.npi = dbi_result_get_uint(result, "src_npi"); sms->src.ton = dbi_result_get_uint(result, "src_ton"); @@ -1236,7 +1225,7 @@ struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, unsigned long long mi result = dbi_conn_queryf(conn, "SELECT SMS.* " "FROM SMS JOIN Subscriber ON " - "SMS.receiver_id = Subscriber.id " + "SMS.dest_addr = Subscriber.extension " "WHERE SMS.id >= %llu AND SMS.sent IS NULL " "AND Subscriber.lac > 0 " "ORDER BY SMS.id LIMIT 1", @@ -1266,10 +1255,10 @@ struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, result = dbi_conn_queryf(conn, "SELECT SMS.* " "FROM SMS JOIN Subscriber ON " - "SMS.receiver_id = Subscriber.id " - "WHERE SMS.receiver_id >= %llu AND SMS.sent IS NULL " + "SMS.dest_addr = Subscriber.extension " + "WHERE Subscriber.id >= %llu AND SMS.sent IS NULL " "AND Subscriber.lac > 0 AND SMS.deliver_attempts < %u " - "ORDER BY SMS.receiver_id, SMS.id LIMIT 1", + "ORDER BY Subscriber.id, SMS.id LIMIT 1", min_subscr_id, failed); if (!result) return NULL; @@ -1295,8 +1284,8 @@ struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr) result = dbi_conn_queryf(conn, "SELECT SMS.* " "FROM SMS JOIN Subscriber ON " - "SMS.receiver_id = Subscriber.id " - "WHERE SMS.receiver_id = %llu AND SMS.sent IS NULL " + "SMS.dest_addr = Subscriber.extension " + "WHERE Subscriber.id = %llu AND SMS.sent IS NULL " "AND Subscriber.lac > 0 " "ORDER BY SMS.id LIMIT 1", subscr->id); -- 1.9.0 From holger at freyther.de Sat Mar 8 12:54:30 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Mar 2014 13:54:30 +0100 Subject: [PATCH 4/4] sms: Add code to migrate the database to the new schema In-Reply-To: <1394283270-32229-1-git-send-email-holger@freyther.de> References: <1394283270-32229-1-git-send-email-holger@freyther.de> Message-ID: <1394283270-32229-4-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther This is mostly based on Alexander's migration code. The code adds transaction handling and some sanity checks and cleanups to the code. We made the decision to fork the sms_from_result method and freeze it to that version. This way sms_from_result can move forward without having to deal with legacy. --- openbsc/src/libbsc/gsm_subscriber_base.c | 6 + openbsc/src/libmsc/db.c | 209 ++++++++++++++++++++++++++++--- 2 files changed, 199 insertions(+), 16 deletions(-) diff --git a/openbsc/src/libbsc/gsm_subscriber_base.c b/openbsc/src/libbsc/gsm_subscriber_base.c index 5755687..5e00443 100644 --- a/openbsc/src/libbsc/gsm_subscriber_base.c +++ b/openbsc/src/libbsc/gsm_subscriber_base.c @@ -72,6 +72,12 @@ static void subscr_free(struct gsm_subscriber *subscr) talloc_free(subscr); } +void subscr_direct_free(struct gsm_subscriber *subscr) +{ + OSMO_ASSERT(subscr->use_count == 1); + subscr_free(subscr); +} + struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr) { subscr->use_count++; diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 2351485..3b92691 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -38,23 +38,42 @@ #include #include +/* Semi-Private-Interface (SPI) for the subscriber code */ +void subscr_direct_free(struct gsm_subscriber *subscr); + static char *db_basename = NULL; static char *db_dirname = NULL; static dbi_conn conn; -#define SCHEMA_REVISION "3" +#define SCHEMA_REVISION "4" + +enum { + SCHEMA_META, + INSERT_META, + SCHEMA_SUBSCRIBER, + SCHEMA_AUTH, + SCHEMA_EQUIPMENT, + SCHEMA_EQUIPMENT_WATCH, + SCHEMA_SMS, + SCHEMA_VLR, + SCHEMA_APDU, + SCHEMA_COUNTERS, + SCHEMA_RATE, + SCHEMA_AUTHKEY, + SCHEMA_AUTHLAST, +}; -static char *create_stmts[] = { - "CREATE TABLE IF NOT EXISTS Meta (" +static const char *create_stmts[] = { + [SCHEMA_META] = "CREATE TABLE IF NOT EXISTS Meta (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "key TEXT UNIQUE NOT NULL, " "value TEXT NOT NULL" ")", - "INSERT OR IGNORE INTO Meta " + [INSERT_META] = "INSERT OR IGNORE INTO Meta " "(key, value) " "VALUES " "('revision', " SCHEMA_REVISION ")", - "CREATE TABLE IF NOT EXISTS Subscriber (" + [SCHEMA_SUBSCRIBER] = "CREATE TABLE IF NOT EXISTS Subscriber (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " @@ -66,13 +85,13 @@ static char *create_stmts[] = { "lac INTEGER NOT NULL DEFAULT 0, " "expire_lu TIMESTAMP DEFAULT NULL" ")", - "CREATE TABLE IF NOT EXISTS AuthToken (" + [SCHEMA_AUTH] = "CREATE TABLE IF NOT EXISTS AuthToken (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "subscriber_id INTEGER UNIQUE NOT NULL, " "created TIMESTAMP NOT NULL, " "token TEXT UNIQUE NOT NULL" ")", - "CREATE TABLE IF NOT EXISTS Equipment (" + [SCHEMA_EQUIPMENT] = "CREATE TABLE IF NOT EXISTS Equipment (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " @@ -82,7 +101,7 @@ static char *create_stmts[] = { "classmark3 BLOB, " "imei NUMERIC UNIQUE NOT NULL" ")", - "CREATE TABLE IF NOT EXISTS EquipmentWatch (" + [SCHEMA_EQUIPMENT_WATCH] = "CREATE TABLE IF NOT EXISTS EquipmentWatch (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " @@ -90,7 +109,7 @@ static char *create_stmts[] = { "equipment_id NUMERIC NOT NULL, " "UNIQUE (subscriber_id, equipment_id) " ")", - "CREATE TABLE IF NOT EXISTS SMS (" + [SCHEMA_SMS] = "CREATE TABLE IF NOT EXISTS SMS (" /* metadata, not part of sms */ "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " @@ -114,39 +133,39 @@ static char *create_stmts[] = { "header BLOB, " /* UD Header */ "text TEXT " /* decoded UD after UDH */ ")", - "CREATE TABLE IF NOT EXISTS VLR (" + [SCHEMA_VLR] = "CREATE TABLE IF NOT EXISTS VLR (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "updated TIMESTAMP NOT NULL, " "subscriber_id NUMERIC UNIQUE NOT NULL, " "last_bts NUMERIC NOT NULL " ")", - "CREATE TABLE IF NOT EXISTS ApduBlobs (" + [SCHEMA_APDU] = "CREATE TABLE IF NOT EXISTS ApduBlobs (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "created TIMESTAMP NOT NULL, " "apdu_id_flags INTEGER NOT NULL, " "subscriber_id INTEGER NOT NULL, " "apdu BLOB " ")", - "CREATE TABLE IF NOT EXISTS Counters (" + [SCHEMA_COUNTERS] = "CREATE TABLE IF NOT EXISTS Counters (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "timestamp TIMESTAMP NOT NULL, " "value INTEGER NOT NULL, " "name TEXT NOT NULL " ")", - "CREATE TABLE IF NOT EXISTS RateCounters (" + [SCHEMA_RATE] = "CREATE TABLE IF NOT EXISTS RateCounters (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "timestamp TIMESTAMP NOT NULL, " "value INTEGER NOT NULL, " "name TEXT NOT NULL, " "idx INTEGER NOT NULL " ")", - "CREATE TABLE IF NOT EXISTS AuthKeys (" + [SCHEMA_AUTHKEY] = "CREATE TABLE IF NOT EXISTS AuthKeys (" "subscriber_id INTEGER PRIMARY KEY, " "algorithm_id INTEGER NOT NULL, " "a3a8_ki BLOB " ")", - "CREATE TABLE IF NOT EXISTS AuthLastTuples (" + [SCHEMA_AUTHLAST] = "CREATE TABLE IF NOT EXISTS AuthLastTuples (" "subscriber_id INTEGER PRIMARY KEY, " "issued TIMESTAMP NOT NULL, " "use_count INTEGER NOT NULL DEFAULT 0, " @@ -185,12 +204,164 @@ static int update_db_revision_2(void) "WHERE key = 'revision'"); if (!result) { LOGP(DDB, LOGL_ERROR, - "Failed set new revision (upgrade vom rev 2).\n"); + "Failed to update DB schema revision (upgrade from rev 2).\n"); + return -EINVAL; + } + dbi_result_free(result); + + return 0; +} + +/** + * Copied from the normal sms_from_result_v3 to avoid having + * to make sure that the real routine will remain backward + * compatible. + */ +static struct gsm_sms *sms_from_result_v3(dbi_result result) +{ + struct gsm_sms *sms = sms_alloc(); + long long unsigned int sender_id; + struct gsm_subscriber *sender; + const char *text, *daddr; + const unsigned char *user_data; + char buf[32]; + + if (!sms) + return NULL; + + sms->id = dbi_result_get_ulonglong(result, "id"); + + sender_id = dbi_result_get_ulonglong(result, "sender_id"); + snprintf(buf, sizeof(buf), "%llu", sender_id); + sender = db_get_subscriber(GSM_SUBSCRIBER_ID, buf); + OSMO_ASSERT(sender); + strncpy(sms->src.addr, sender->extension, sizeof(sms->src.addr)-1); + subscr_direct_free(sender); + sender = NULL; + + sms->reply_path_req = dbi_result_get_uint(result, "reply_path_req"); + sms->status_rep_req = dbi_result_get_uint(result, "status_rep_req"); + sms->ud_hdr_ind = dbi_result_get_uint(result, "ud_hdr_ind"); + sms->protocol_id = dbi_result_get_uint(result, "protocol_id"); + sms->data_coding_scheme = dbi_result_get_uint(result, + "data_coding_scheme"); + + daddr = dbi_result_get_string(result, "dest_addr"); + if (daddr) { + strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); + sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0'; + } + + sms->user_data_len = dbi_result_get_field_length(result, "user_data"); + user_data = dbi_result_get_binary(result, "user_data"); + if (sms->user_data_len > sizeof(sms->user_data)) + sms->user_data_len = (uint8_t) sizeof(sms->user_data); + memcpy(sms->user_data, user_data, sms->user_data_len); + + text = dbi_result_get_string(result, "text"); + if (text) { + strncpy(sms->text, text, sizeof(sms->text)); + sms->text[sizeof(sms->text)-1] = '\0'; + } + return sms; +} + +static int update_db_revision_3(void) +{ + dbi_result result; + struct gsm_sms *sms; + + result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to begin transaction (upgrade from rev 3)\n"); return -EINVAL; } dbi_result_free(result); + /* Rename old SMS table to be able create a new one */ + result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to rename the old SMS table (upgrade from rev 3).\n"); + goto rollback; + } + dbi_result_free(result); + + /* Create new SMS table with all the bells and whistles! */ + result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to create a new SMS table (upgrade from rev 3).\n"); + goto rollback; + } + dbi_result_free(result); + + /* Cycle through old messages and convert them to the new format */ + result = dbi_conn_queryf(conn, "SELECT * FROM SMS_3"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed fetch messages from the old SMS table (upgrade from rev 3).\n"); + goto rollback; + } + while (dbi_result_next_row(result)) { + sms = sms_from_result_v3(result); + if (db_sms_store(sms) != 0) { + LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 3).\n"); + sms_free(sms); + dbi_result_free(result); + goto rollback; + } + sms_free(sms); + } + dbi_result_free(result); + + /* Remove the temporary table */ + result = dbi_conn_query(conn, "DROP TABLE SMS_3"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to drop the old SMS table (upgrade from rev 3).\n"); + goto rollback; + } + dbi_result_free(result); + + /* We're done. Bump DB Meta revision to 4 */ + result = dbi_conn_query(conn, + "UPDATE Meta " + "SET value = '4' " + "WHERE key = 'revision'"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to update DB schema revision (upgrade from rev 3).\n"); + goto rollback; + } + dbi_result_free(result); + + result = dbi_conn_query(conn, "COMMIT TRANSACTION"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to commit the transaction (upgrade from rev 3)\n"); + return -EINVAL; + } + + /* Shrink DB file size by actually wiping out SMS_3 table data */ + result = dbi_conn_query(conn, "VACUUM"); + if (!result) + LOGP(DDB, LOGL_ERROR, + "VACUUM failed. Ignoring it (upgrade from rev 3).\n"); + else + dbi_result_free(result); + return 0; + +rollback: + result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); + if (!result) + LOGP(DDB, LOGL_ERROR, + "Rollback failed (upgrade from rev 3).\n"); + else + dbi_result_free(result); + return -EINVAL; } static int check_db_revision(void) @@ -218,6 +389,12 @@ static int check_db_revision(void) dbi_result_free(result); return -EINVAL; } + } else if (!strcmp(rev_s, "3")) { + if (update_db_revision_3()) { + LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%s'.\n", rev_s); + dbi_result_free(result); + return -EINVAL; + } } else if (!strcmp(rev_s, SCHEMA_REVISION)) { /* everything is fine */ } else { -- 1.9.0 From alexander.chemeris at gmail.com Sat Mar 8 13:58:46 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 14:58:46 +0100 Subject: [PATCH 4/4] sms: Add code to migrate the database to the new schema In-Reply-To: <1394283270-32229-4-git-send-email-holger@freyther.de> References: <1394283270-32229-1-git-send-email-holger@freyther.de> <1394283270-32229-4-git-send-email-holger@freyther.de> Message-ID: Hi Holger, Thank you for improving robustness of the code. I looked through it and it looks good to me. Please let me know when you merge to the master so I could rebase the SMS validity decoding code on top of it and submit it for review. On Sat, Mar 8, 2014 at 1:54 PM, Holger Hans Peter Freyther < holger at freyther.de> wrote: > From: Holger Hans Peter Freyther > > This is mostly based on Alexander's migration code. The code > adds transaction handling and some sanity checks and cleanups > to the code. We made the decision to fork the sms_from_result > method and freeze it to that version. This way sms_from_result > can move forward without having to deal with legacy. > --- > openbsc/src/libbsc/gsm_subscriber_base.c | 6 + > openbsc/src/libmsc/db.c | 209 > ++++++++++++++++++++++++++++--- > 2 files changed, 199 insertions(+), 16 deletions(-) > > diff --git a/openbsc/src/libbsc/gsm_subscriber_base.c > b/openbsc/src/libbsc/gsm_subscriber_base.c > index 5755687..5e00443 100644 > --- a/openbsc/src/libbsc/gsm_subscriber_base.c > +++ b/openbsc/src/libbsc/gsm_subscriber_base.c > @@ -72,6 +72,12 @@ static void subscr_free(struct gsm_subscriber *subscr) > talloc_free(subscr); > } > > +void subscr_direct_free(struct gsm_subscriber *subscr) > +{ > + OSMO_ASSERT(subscr->use_count == 1); > + subscr_free(subscr); > +} > + > struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr) > { > subscr->use_count++; > diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c > index 2351485..3b92691 100644 > --- a/openbsc/src/libmsc/db.c > +++ b/openbsc/src/libmsc/db.c > @@ -38,23 +38,42 @@ > #include > #include > > +/* Semi-Private-Interface (SPI) for the subscriber code */ > +void subscr_direct_free(struct gsm_subscriber *subscr); > + > static char *db_basename = NULL; > static char *db_dirname = NULL; > static dbi_conn conn; > > -#define SCHEMA_REVISION "3" > +#define SCHEMA_REVISION "4" > + > +enum { > + SCHEMA_META, > + INSERT_META, > + SCHEMA_SUBSCRIBER, > + SCHEMA_AUTH, > + SCHEMA_EQUIPMENT, > + SCHEMA_EQUIPMENT_WATCH, > + SCHEMA_SMS, > + SCHEMA_VLR, > + SCHEMA_APDU, > + SCHEMA_COUNTERS, > + SCHEMA_RATE, > + SCHEMA_AUTHKEY, > + SCHEMA_AUTHLAST, > +}; > > -static char *create_stmts[] = { > - "CREATE TABLE IF NOT EXISTS Meta (" > +static const char *create_stmts[] = { > + [SCHEMA_META] = "CREATE TABLE IF NOT EXISTS Meta (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "key TEXT UNIQUE NOT NULL, " > "value TEXT NOT NULL" > ")", > - "INSERT OR IGNORE INTO Meta " > + [INSERT_META] = "INSERT OR IGNORE INTO Meta " > "(key, value) " > "VALUES " > "('revision', " SCHEMA_REVISION ")", > - "CREATE TABLE IF NOT EXISTS Subscriber (" > + [SCHEMA_SUBSCRIBER] = "CREATE TABLE IF NOT EXISTS Subscriber (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > "updated TIMESTAMP NOT NULL, " > @@ -66,13 +85,13 @@ static char *create_stmts[] = { > "lac INTEGER NOT NULL DEFAULT 0, " > "expire_lu TIMESTAMP DEFAULT NULL" > ")", > - "CREATE TABLE IF NOT EXISTS AuthToken (" > + [SCHEMA_AUTH] = "CREATE TABLE IF NOT EXISTS AuthToken (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "subscriber_id INTEGER UNIQUE NOT NULL, " > "created TIMESTAMP NOT NULL, " > "token TEXT UNIQUE NOT NULL" > ")", > - "CREATE TABLE IF NOT EXISTS Equipment (" > + [SCHEMA_EQUIPMENT] = "CREATE TABLE IF NOT EXISTS Equipment (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > "updated TIMESTAMP NOT NULL, " > @@ -82,7 +101,7 @@ static char *create_stmts[] = { > "classmark3 BLOB, " > "imei NUMERIC UNIQUE NOT NULL" > ")", > - "CREATE TABLE IF NOT EXISTS EquipmentWatch (" > + [SCHEMA_EQUIPMENT_WATCH] = "CREATE TABLE IF NOT EXISTS > EquipmentWatch (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > "updated TIMESTAMP NOT NULL, " > @@ -90,7 +109,7 @@ static char *create_stmts[] = { > "equipment_id NUMERIC NOT NULL, " > "UNIQUE (subscriber_id, equipment_id) " > ")", > - "CREATE TABLE IF NOT EXISTS SMS (" > + [SCHEMA_SMS] = "CREATE TABLE IF NOT EXISTS SMS (" > /* metadata, not part of sms */ > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > @@ -114,39 +133,39 @@ static char *create_stmts[] = { > "header BLOB, " /* UD Header */ > "text TEXT " /* decoded UD after UDH */ > ")", > - "CREATE TABLE IF NOT EXISTS VLR (" > + [SCHEMA_VLR] = "CREATE TABLE IF NOT EXISTS VLR (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > "updated TIMESTAMP NOT NULL, " > "subscriber_id NUMERIC UNIQUE NOT NULL, " > "last_bts NUMERIC NOT NULL " > ")", > - "CREATE TABLE IF NOT EXISTS ApduBlobs (" > + [SCHEMA_APDU] = "CREATE TABLE IF NOT EXISTS ApduBlobs (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "created TIMESTAMP NOT NULL, " > "apdu_id_flags INTEGER NOT NULL, " > "subscriber_id INTEGER NOT NULL, " > "apdu BLOB " > ")", > - "CREATE TABLE IF NOT EXISTS Counters (" > + [SCHEMA_COUNTERS] = "CREATE TABLE IF NOT EXISTS Counters (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "timestamp TIMESTAMP NOT NULL, " > "value INTEGER NOT NULL, " > "name TEXT NOT NULL " > ")", > - "CREATE TABLE IF NOT EXISTS RateCounters (" > + [SCHEMA_RATE] = "CREATE TABLE IF NOT EXISTS RateCounters (" > "id INTEGER PRIMARY KEY AUTOINCREMENT, " > "timestamp TIMESTAMP NOT NULL, " > "value INTEGER NOT NULL, " > "name TEXT NOT NULL, " > "idx INTEGER NOT NULL " > ")", > - "CREATE TABLE IF NOT EXISTS AuthKeys (" > + [SCHEMA_AUTHKEY] = "CREATE TABLE IF NOT EXISTS AuthKeys (" > "subscriber_id INTEGER PRIMARY KEY, " > "algorithm_id INTEGER NOT NULL, " > "a3a8_ki BLOB " > ")", > - "CREATE TABLE IF NOT EXISTS AuthLastTuples (" > + [SCHEMA_AUTHLAST] = "CREATE TABLE IF NOT EXISTS AuthLastTuples (" > "subscriber_id INTEGER PRIMARY KEY, " > "issued TIMESTAMP NOT NULL, " > "use_count INTEGER NOT NULL DEFAULT 0, " > @@ -185,12 +204,164 @@ static int update_db_revision_2(void) > "WHERE key = 'revision'"); > if (!result) { > LOGP(DDB, LOGL_ERROR, > - "Failed set new revision (upgrade vom rev 2).\n"); > + "Failed to update DB schema revision (upgrade from > rev 2).\n"); > + return -EINVAL; > + } > + dbi_result_free(result); > + > + return 0; > +} > + > +/** > + * Copied from the normal sms_from_result_v3 to avoid having > + * to make sure that the real routine will remain backward > + * compatible. > + */ > +static struct gsm_sms *sms_from_result_v3(dbi_result result) > +{ > + struct gsm_sms *sms = sms_alloc(); > + long long unsigned int sender_id; > + struct gsm_subscriber *sender; > + const char *text, *daddr; > + const unsigned char *user_data; > + char buf[32]; > + > + if (!sms) > + return NULL; > + > + sms->id = dbi_result_get_ulonglong(result, "id"); > + > + sender_id = dbi_result_get_ulonglong(result, "sender_id"); > + snprintf(buf, sizeof(buf), "%llu", sender_id); > + sender = db_get_subscriber(GSM_SUBSCRIBER_ID, buf); > + OSMO_ASSERT(sender); > + strncpy(sms->src.addr, sender->extension, sizeof(sms->src.addr)-1); > + subscr_direct_free(sender); > + sender = NULL; > + > + sms->reply_path_req = dbi_result_get_uint(result, > "reply_path_req"); > + sms->status_rep_req = dbi_result_get_uint(result, > "status_rep_req"); > + sms->ud_hdr_ind = dbi_result_get_uint(result, "ud_hdr_ind"); > + sms->protocol_id = dbi_result_get_uint(result, "protocol_id"); > + sms->data_coding_scheme = dbi_result_get_uint(result, > + "data_coding_scheme"); > + > + daddr = dbi_result_get_string(result, "dest_addr"); > + if (daddr) { > + strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); > + sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0'; > + } > + > + sms->user_data_len = dbi_result_get_field_length(result, > "user_data"); > + user_data = dbi_result_get_binary(result, "user_data"); > + if (sms->user_data_len > sizeof(sms->user_data)) > + sms->user_data_len = (uint8_t) sizeof(sms->user_data); > + memcpy(sms->user_data, user_data, sms->user_data_len); > + > + text = dbi_result_get_string(result, "text"); > + if (text) { > + strncpy(sms->text, text, sizeof(sms->text)); > + sms->text[sizeof(sms->text)-1] = '\0'; > + } > + return sms; > +} > + > +static int update_db_revision_3(void) > +{ > + dbi_result result; > + struct gsm_sms *sms; > + > + result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to begin transaction (upgrade from rev > 3)\n"); > return -EINVAL; > } > dbi_result_free(result); > > + /* Rename old SMS table to be able create a new one */ > + result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to rename the old SMS table (upgrade from rev > 3).\n"); > + goto rollback; > + } > + dbi_result_free(result); > + > + /* Create new SMS table with all the bells and whistles! */ > + result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to create a new SMS table (upgrade from rev > 3).\n"); > + goto rollback; > + } > + dbi_result_free(result); > + > + /* Cycle through old messages and convert them to the new format */ > + result = dbi_conn_queryf(conn, "SELECT * FROM SMS_3"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed fetch messages from the old SMS table > (upgrade from rev 3).\n"); > + goto rollback; > + } > + while (dbi_result_next_row(result)) { > + sms = sms_from_result_v3(result); > + if (db_sms_store(sms) != 0) { > + LOGP(DDB, LOGL_ERROR, "Failed to store message to > the new SMS table(upgrade from rev 3).\n"); > + sms_free(sms); > + dbi_result_free(result); > + goto rollback; > + } > + sms_free(sms); > + } > + dbi_result_free(result); > + > + /* Remove the temporary table */ > + result = dbi_conn_query(conn, "DROP TABLE SMS_3"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to drop the old SMS table (upgrade from rev > 3).\n"); > + goto rollback; > + } > + dbi_result_free(result); > + > + /* We're done. Bump DB Meta revision to 4 */ > + result = dbi_conn_query(conn, > + "UPDATE Meta " > + "SET value = '4' " > + "WHERE key = 'revision'"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to update DB schema revision (upgrade from > rev 3).\n"); > + goto rollback; > + } > + dbi_result_free(result); > + > + result = dbi_conn_query(conn, "COMMIT TRANSACTION"); > + if (!result) { > + LOGP(DDB, LOGL_ERROR, > + "Failed to commit the transaction (upgrade from > rev 3)\n"); > + return -EINVAL; > + } > + > + /* Shrink DB file size by actually wiping out SMS_3 table data */ > + result = dbi_conn_query(conn, "VACUUM"); > + if (!result) > + LOGP(DDB, LOGL_ERROR, > + "VACUUM failed. Ignoring it (upgrade from rev > 3).\n"); > + else > + dbi_result_free(result); > + > return 0; > + > +rollback: > + result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); > + if (!result) > + LOGP(DDB, LOGL_ERROR, > + "Rollback failed (upgrade from rev 3).\n"); > + else > + dbi_result_free(result); > + return -EINVAL; > } > > static int check_db_revision(void) > @@ -218,6 +389,12 @@ static int check_db_revision(void) > dbi_result_free(result); > return -EINVAL; > } > + } else if (!strcmp(rev_s, "3")) { > + if (update_db_revision_3()) { > + LOGP(DDB, LOGL_FATAL, "Failed to update database > from schema revision '%s'.\n", rev_s); > + dbi_result_free(result); > + return -EINVAL; > + } > } else if (!strcmp(rev_s, SCHEMA_REVISION)) { > /* everything is fine */ > } else { > -- > 1.9.0 > > > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Sat Mar 8 15:53:12 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 16:53:12 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. Message-ID: This is a continuation of the patch series for the SMS validity fixes in libosmocore. Note, that this patch is based on top of the SMS DB change to remove receiver ID. It is also available in the achemeris/sms-validity-fix-master branch in the git repo. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-libmsc-sms-Properly-calculate-and-store-validity-and.patch Type: text/x-patch Size: 5745 bytes Desc: not available URL: From holger at freyther.de Sat Mar 8 16:49:11 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Mar 2014 17:49:11 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: References: Message-ID: <20140308164911.GA4815@xiaoyu.lan> On Sat, Mar 08, 2014 at 04:53:12PM +0100, Alexander Chemeris wrote: > - "(datetime('now'), %u, " > + "(%s, %s, " ... > - validity_timestamp, > + received_timestamp, validity_timestamp, Please do not change the created to be the received timestamp. If you want to have a received_timestamp then introduce it. In case you hurry up we can get it into schema version 4. From alexander.chemeris at gmail.com Sat Mar 8 18:50:30 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 19:50:30 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: <20140308164911.GA4815@xiaoyu.lan> References: <20140308164911.GA4815@xiaoyu.lan> Message-ID: On Sat, Mar 8, 2014 at 5:49 PM, Holger Hans Peter Freyther wrote: > > On Sat, Mar 08, 2014 at 04:53:12PM +0100, Alexander Chemeris wrote: > > > - "(datetime('now'), %u, " > > + "(%s, %s, " > > ... > > > - validity_timestamp, > > + received_timestamp, validity_timestamp, > > Please do not change the created to be the received timestamp. If you > want to have a received_timestamp then introduce it. In case you hurry > up we can get it into schema version 4. I don't see any immediate needs for having created timestamps, but I agree that it's a good idea to keep it. The updated patch is attached and the branch is updated. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-libmsc-sms-Properly-calculate-and-store-validity-and.patch Type: text/x-patch Size: 6594 bytes Desc: not available URL: From peter at stuge.se Sat Mar 8 18:58:15 2014 From: peter at stuge.se (Peter Stuge) Date: Sat, 8 Mar 2014 19:58:15 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: References: <20140308164911.GA4815@xiaoyu.lan> Message-ID: <20140308185815.17226.qmail@stuge.se> Alexander Chemeris wrote: > +++ b/openbsc/src/libmsc/gsm_04_11.c > @@ -102,6 +102,10 @@ struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, > sms->protocol_id = 0; /* implicit */ > sms->data_coding_scheme = dcs; > strncpy(sms->dst.addr, receiver->extension, sizeof(sms->dst.addr)-1); > + /* Timestamps */ > + time(&sms->received_time); > + time(&sms->valid_until); > + sms->valid_until += SMS_DEFAULT_VALIDITY_PERIOD; In order to make this a bit more atomic I'd suggest replacing the second time() with reuse of the first value. sms->valid_until = sms->received_time + SMS_DEFAULT_VALIDITY_PERIOD; The INSERT statement change is pretty gross but oh well. //Peter From alexander.chemeris at gmail.com Sat Mar 8 19:28:44 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 20:28:44 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: <20140308185815.17226.qmail@stuge.se> References: <20140308164911.GA4815@xiaoyu.lan> <20140308185815.17226.qmail@stuge.se> Message-ID: On Sat, Mar 8, 2014 at 7:58 PM, Peter Stuge wrote: > Alexander Chemeris wrote: >> +++ b/openbsc/src/libmsc/gsm_04_11.c >> @@ -102,6 +102,10 @@ struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, >> sms->protocol_id = 0; /* implicit */ >> sms->data_coding_scheme = dcs; >> strncpy(sms->dst.addr, receiver->extension, sizeof(sms->dst.addr)-1); >> + /* Timestamps */ >> + time(&sms->received_time); >> + time(&sms->valid_until); >> + sms->valid_until += SMS_DEFAULT_VALIDITY_PERIOD; > > In order to make this a bit more atomic I'd suggest replacing the > second time() with reuse of the first value. > > sms->valid_until = sms->received_time + SMS_DEFAULT_VALIDITY_PERIOD; Good idea. Not sure why I didn't have this before. I've updated the branch. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Sat Mar 8 21:16:25 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 22:16:25 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: <20140308164911.GA4815@xiaoyu.lan> References: <20140308164911.GA4815@xiaoyu.lan> Message-ID: On Sat, Mar 8, 2014 at 5:49 PM, Holger Hans Peter Freyther wrote: > In case you hurry up we can get it into schema version 4. I've submitted one more patch, affecting the DB scheme. I hope we could include it into the same batch of DB changes. [PATCH 2/2] sms,db: Do not store delivered messages in the DB. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From holger at freyther.de Tue Mar 11 13:33:47 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Mar 2014 14:33:47 +0100 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: References: <20140308164911.GA4815@xiaoyu.lan> Message-ID: <20140311133347.GE17965@xiaoyu.lan> On Sat, Mar 08, 2014 at 10:16:25PM +0100, Alexander Chemeris wrote: > On Sat, Mar 8, 2014 at 5:49 PM, Holger Hans Peter Freyther > wrote: > > In case you hurry up we can get it into schema version 4. > > I've submitted one more patch, affecting the DB scheme. I hope we > could include it into the same batch of DB changes. > [PATCH 2/2] sms,db: Do not store delivered messages in the DB. Sure. We should do all the schema changes now. From alexander.chemeris at gmail.com Wed Mar 12 17:26:17 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 21:26:17 +0400 Subject: [PATCH] libmsc,sms: Properly calculate and store validity and received timestamps for incoming SMS. In-Reply-To: <20140311133347.GE17965@xiaoyu.lan> References: <20140308164911.GA4815@xiaoyu.lan> <20140311133347.GE17965@xiaoyu.lan> Message-ID: I've updated the patch due to gsm340_validity_time() function rename. On Tue, Mar 11, 2014 at 5:33 PM, Holger Hans Peter Freyther wrote: > On Sat, Mar 08, 2014 at 10:16:25PM +0100, Alexander Chemeris wrote: >> On Sat, Mar 8, 2014 at 5:49 PM, Holger Hans Peter Freyther >> wrote: >> > In case you hurry up we can get it into schema version 4. >> >> I've submitted one more patch, affecting the DB scheme. I hope we >> could include it into the same batch of DB changes. >> [PATCH 2/2] sms,db: Do not store delivered messages in the DB. > > Sure. We should do all the schema changes now. > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-libmsc-sms-Properly-calculate-and-store-validity-and.patch Type: text/x-patch Size: 6583 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sat Mar 8 18:52:54 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 19:52:54 +0100 Subject: [PATCH] db: Add more tests for retrieving subscribers from a DB. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-db-Add-more-tests-for-retrieving-subscribers-from-a-.patch Type: text/x-patch Size: 3010 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sat Mar 8 21:09:50 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 22:09:50 +0100 Subject: [PATCH 1/2] db, sms: Rename db_sms_mark_sent() to db_sms_mark_delivered(), as that's what it does. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-db-sms-Rename-db_sms_mark_sent-to-db_sms_mark_delive.patch Type: text/x-patch Size: 2085 bytes Desc: not available URL: From holger at freyther.de Sun Mar 9 09:31:04 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 10:31:04 +0100 Subject: [PATCH 1/2] db, sms: Rename db_sms_mark_sent() to db_sms_mark_delivered(), as that's what it does. In-Reply-To: References: Message-ID: <20140309093104.GC28429@xiaoyu.lan> On Sat, Mar 08, 2014 at 10:09:50PM +0100, Alexander Chemeris wrote: applied with a different commit message. We should rename "sent" to "delivered" too. Yes, I know in your second patch you want to remove it. From alexander.chemeris at gmail.com Sun Mar 9 10:29:35 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:29:35 +0100 Subject: [PATCH 1/2] db, sms: Rename db_sms_mark_sent() to db_sms_mark_delivered(), as that's what it does. In-Reply-To: <20140309093104.GC28429@xiaoyu.lan> References: <20140309093104.GC28429@xiaoyu.lan> Message-ID: Thanks. On Sun, Mar 9, 2014 at 10:31 AM, Holger Hans Peter Freyther wrote: > On Sat, Mar 08, 2014 at 10:09:50PM +0100, Alexander Chemeris wrote: > > applied with a different commit message. We should rename "sent" to > "delivered" too. Yes, I know in your second patch you want to remove > it. > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Sat Mar 8 21:11:03 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Mar 2014 22:11:03 +0100 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. Message-ID: In a production system we should not store messages longer than needed, as it will quickly bloat our DB. In case one wants to store messages for debug purposes, we could add one of the following capabilities later: - hexdump to a log file - send to an SMPP entry on delivery - send to Wireshark -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-sms-db-Do-not-store-delivered-messages-in-the-DB.patch Type: text/x-patch Size: 3312 bytes Desc: not available URL: From holger at freyther.de Sun Mar 9 09:36:33 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 10:36:33 +0100 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. In-Reply-To: References: Message-ID: <20140309093633.GD28429@xiaoyu.lan> On Sat, Mar 08, 2014 at 10:11:03PM +0100, Alexander Chemeris wrote: Good Morning, > In a production system we should not store messages longer than > needed, as it will quickly bloat our DB. In case one wants to store > messages for debug purposes, we could add one of the following > capabilities later: > - hexdump to a log file > - send to an SMPP entry on delivery > - send to Wireshark there are several aspects in "production". There is billing and privacy. For privacy we should clear the text/user_data after the SMS has been delivered. For billing one might need to keep the meta data up to X (e.g. 90) days. As we don't have a "CDR" mdoule the only way to handle it is to keep that in the DB. So I wouldn't want to remove this right now. holger From alexander.chemeris at gmail.com Sun Mar 9 10:29:09 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:29:09 +0100 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. In-Reply-To: <20140309093633.GD28429@xiaoyu.lan> References: <20140309093633.GD28429@xiaoyu.lan> Message-ID: Hi Holger, On Sun, Mar 9, 2014 at 10:36 AM, Holger Hans Peter Freyther wrote: > On Sat, Mar 08, 2014 at 10:11:03PM +0100, Alexander Chemeris wrote: >> In a production system we should not store messages longer than >> needed, as it will quickly bloat our DB. In case one wants to store >> messages for debug purposes, we could add one of the following >> capabilities later: >> - hexdump to a log file >> - send to an SMPP entry on delivery >> - send to Wireshark > > there are several aspects in "production". There is billing and > privacy. For privacy we should clear the text/user_data after the > SMS has been delivered. For billing one might need to keep the meta > data up to X (e.g. 90) days. As we don't have a "CDR" mdoule the only > way to handle it is to keep that in the DB. > > So I wouldn't want to remove this right now. If you want billing, you could route all messages to SMPP, route/ACL/bill there and send them back to the internal SMSC. That's what Rhizomatica guys are doing and it works well. In this outside SMPP entity you could do whatever CDR and storage you want, without touching the OpenBSC code, which is in line with our discussions with Harald. PS I have more DB changes pending. One is storing Message Reference in the DB to be able to generate delivery reports (commited to my branch). The other is not finished yet, which will allow store delivery reports in the DB. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From holger at freyther.de Tue Mar 11 14:10:35 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Mar 2014 15:10:35 +0100 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. In-Reply-To: References: <20140309093633.GD28429@xiaoyu.lan> Message-ID: <20140311141035.GF17965@xiaoyu.lan> On Sun, Mar 09, 2014 at 11:29:09AM +0100, Alexander Chemeris wrote: > If you want billing, you could route all messages to SMPP, > route/ACL/bill there and send them back to the internal SMSC. That's > what Rhizomatica guys are doing and it works well. In this outside > SMPP entity you could do whatever CDR and storage you want, without > touching the OpenBSC code, which is in line with our discussions with > Harald. The same argument applies to your initial patch. I am not comfortable with deleting SMS from the database right away. I understand the privacy issue we have for XX3C events where we would want to clear the user content after the SMS has been sent. And I understand the need for cleaning the DB to save space. But the immediate removal troubles me. From ciaby at autistici.org Tue Mar 11 14:21:38 2014 From: ciaby at autistici.org (Ciaby) Date: Tue, 11 Mar 2014 15:21:38 +0100 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. In-Reply-To: <20140311141035.GF17965@xiaoyu.lan> References: <20140309093633.GD28429@xiaoyu.lan> <20140311141035.GF17965@xiaoyu.lan> Message-ID: <531F1BF2.2010302@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 03/11/2014 03:10 PM, Holger Hans Peter Freyther wrote: [...] > The same argument applies to your initial patch. I am not > comfortable with deleting SMS from the database right away. I > understand the privacy issue we have for XX3C events where we would > want to clear the user content after the SMS has been sent. And I > understand the need for cleaning the DB to save space. But the > immediate removal troubles me. Could it be defined as a config option? ;) Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREKAAYFAlMfG+0ACgkQC30ZhxNccpH8rgD9H9cVaZa+AyO5Xg0Z1UDqCBER 6sVj9/iWEVq6YBWkvloBAI6N+GR8gZ62Qf7mVnivRhn8Dw+PJBVCyiqwxwr92Oo2 =m+p9 -----END PGP SIGNATURE----- From alexander.chemeris at gmail.com Tue Mar 11 16:22:57 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 11 Mar 2014 20:22:57 +0400 Subject: [PATCH 2/2] sms,db: Do not store delivered messages in the DB. In-Reply-To: <531F1BF2.2010302@autistici.org> References: <20140309093633.GD28429@xiaoyu.lan> <20140311141035.GF17965@xiaoyu.lan> <531F1BF2.2010302@autistici.org> Message-ID: On Tue, Mar 11, 2014 at 6:21 PM, Ciaby wrote: > On 03/11/2014 03:10 PM, Holger Hans Peter Freyther wrote: > [...] >> The same argument applies to your initial patch. I am not >> comfortable with deleting SMS from the database right away. I >> understand the privacy issue we have for XX3C events where we would >> want to clear the user content after the SMS has been sent. And I >> understand the need for cleaning the DB to save space. But the >> immediate removal troubles me. > Could it be defined as a config option? ;) Yeah, I think I'll add a config option for that. It'll take some time, as I'm swamped with e-mail after two weeks of travel now. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Sun Mar 9 10:52:33 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:52:33 +0100 Subject: [PATCH] sms: Fix typo in a macros name: GSM340_SMS_RESERVED -> GSM340_SMS_RESERVED. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Fix-typo-in-a-macros-name-GSM340_SMS_RESERVED-GS.patch Type: text/x-patch Size: 922 bytes Desc: not available URL: From alexander.chemeris at gmail.com Mon Mar 10 19:20:20 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 10 Mar 2014 20:20:20 +0100 Subject: [PATCH] sms: Fix typo in a macros name: GSM340_SMS_RESERVED -> GSM340_SMS_RESERVED. In-Reply-To: References: Message-ID: Now with a proper commit message. Should be ready for merge into master, as it doesn't depend on anything. On Sun, Mar 9, 2014 at 11:52 AM, Alexander Chemeris wrote: > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Fix-typo-in-a-macros-name-GSM340_SMS_RESSERVED-G.patch Type: text/x-patch Size: 923 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 9 10:54:56 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:54:56 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). Message-ID: An according change in the OpoenBSC is following. Since we're changing the external API we should probably increase a lib version as well. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Rename-gsm340_gen_oa-to-gsm340_gen_address_field.patch Type: text/x-patch Size: 4847 bytes Desc: not available URL: From holger at freyther.de Sun Mar 9 18:23:23 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 19:23:23 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: References: Message-ID: <20140309182323.GA17965@xiaoyu.lan> On Sun, Mar 09, 2014 at 11:54:56AM +0100, Alexander Chemeris wrote: > An according change in the OpoenBSC is following. > > Since we're changing the external API we should probably increase a > lib version as well. Hi, to ease migration it is easier if you introduce a new method and deprecate the other. Otherwise OpenBSC requires an unreleased version of libosmocore. Otherwise it is a basic rename. :) From alexander.chemeris at gmail.com Mon Mar 10 18:40:51 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 10 Mar 2014 19:40:51 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: <20140309182323.GA17965@xiaoyu.lan> References: <20140309182323.GA17965@xiaoyu.lan> Message-ID: Good idea. An updated patch is attached. On Sun, Mar 9, 2014 at 7:23 PM, Holger Hans Peter Freyther wrote: > On Sun, Mar 09, 2014 at 11:54:56AM +0100, Alexander Chemeris wrote: >> An according change in the OpoenBSC is following. >> >> Since we're changing the external API we should probably increase a >> lib version as well. > > > Hi, > > to ease migration it is easier if you introduce a new method and > deprecate the other. Otherwise OpenBSC requires an unreleased version > of libosmocore. Otherwise it is a basic rename. :) > -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Rename-gsm340_gen_oa-to-gsm340_gen_address_field.patch Type: text/x-patch Size: 5615 bytes Desc: not available URL: From holger at freyther.de Tue Mar 11 14:26:26 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Mar 2014 15:26:26 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: References: <20140309182323.GA17965@xiaoyu.lan> Message-ID: <20140311142626.GH17965@xiaoyu.lan> On Mon, Mar 10, 2014 at 07:40:51PM +0100, Alexander Chemeris wrote: > Good idea. An updated patch is attached. > +/* DEPRECATED: use gsm340_gen_address_field() instead */ > +int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type, > + uint8_t plan, const char *number) OSMO_DEPRECATED("Use gsm340_gen_address_field() instead"); this comment doesn't really add any value. You are using OSMO_DEPRECTAED but you do not directly/indirectly the header file defining it. In fact gsm0411_smc.c fails to compile due this. From alexander.chemeris at gmail.com Tue Mar 11 16:16:49 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 11 Mar 2014 20:16:49 +0400 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: <20140311142626.GH17965@xiaoyu.lan> References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> Message-ID: On Tue, Mar 11, 2014 at 6:26 PM, Holger Hans Peter Freyther wrote: > On Mon, Mar 10, 2014 at 07:40:51PM +0100, Alexander Chemeris wrote: >> Good idea. An updated patch is attached. > >> +/* DEPRECATED: use gsm340_gen_address_field() instead */ >> +int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type, >> + uint8_t plan, const char *number) OSMO_DEPRECATED("Use gsm340_gen_address_field() instead"); > > this comment doesn't really add any value. I don't see how it harms either. Though I've removed it in the attached patch. > You are using OSMO_DEPRECTAED > but you do not directly/indirectly the header file defining it. In fact > gsm0411_smc.c fails to compile due this. Oops, forgot to include this in the patch, my apologies. Updated patch is attached. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Fix-typo-in-a-macros-name-GSM340_SMS_RESSERVED-G.patch Type: text/x-patch Size: 923 bytes Desc: not available URL: From holger at freyther.de Wed Mar 12 12:37:02 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 12 Mar 2014 13:37:02 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> Message-ID: <20140312123702.GD2460@xiaoyu.lan> On Tue, Mar 11, 2014 at 08:16:49PM +0400, Alexander Chemeris wrote: > > You are using OSMO_DEPRECTAED > > but you do not directly/indirectly the header file defining it. In fact > > gsm0411_smc.c fails to compile due this. > > Oops, forgot to include this in the patch, my apologies. > Updated patch is attached. wrong patch. I merged this one anyway after grepping my checkouts for the typo. From alexander.chemeris at gmail.com Wed Mar 12 13:05:26 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 12 Mar 2014 17:05:26 +0400 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: <20140312123702.GD2460@xiaoyu.lan> References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> <20140312123702.GD2460@xiaoyu.lan> Message-ID: On Wed, Mar 12, 2014 at 4:37 PM, Holger Hans Peter Freyther wrote: > On Tue, Mar 11, 2014 at 08:16:49PM +0400, Alexander Chemeris wrote: >> > You are using OSMO_DEPRECTAED >> > but you do not directly/indirectly the header file defining it. In fact >> > gsm0411_smc.c fails to compile due this. >> >> Oops, forgot to include this in the patch, my apologies. >> Updated patch is attached. > > wrong patch. I merged this one anyway after grepping my checkouts > for the typo. Sorry, the correct patch attached. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Rename-gsm340_gen_oa-to-gsm340_gen_address_field.patch Type: text/x-patch Size: 5541 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 16 09:50:10 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 13:50:10 +0400 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> <20140312123702.GD2460@xiaoyu.lan> Message-ID: Hi Holger, It seems there are no more comments on this code. Could you please merge it? It is independent of other changes. On Wed, Mar 12, 2014 at 5:05 PM, Alexander Chemeris wrote: > On Wed, Mar 12, 2014 at 4:37 PM, Holger Hans Peter Freyther > wrote: >> On Tue, Mar 11, 2014 at 08:16:49PM +0400, Alexander Chemeris wrote: >>> > You are using OSMO_DEPRECTAED >>> > but you do not directly/indirectly the header file defining it. In fact >>> > gsm0411_smc.c fails to compile due this. >>> >>> Oops, forgot to include this in the patch, my apologies. >>> Updated patch is attached. >> >> wrong patch. I merged this one anyway after grepping my checkouts >> for the typo. > > Sorry, the correct patch attached. > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves, Inc. / ??? ??????? > https://fairwaves.co -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From holger at freyther.de Wed Mar 26 19:22:22 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 26 Mar 2014 20:22:22 +0100 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> <20140312123702.GD2460@xiaoyu.lan> Message-ID: <20140326192222.GA769@xiaoyu.lan> On Sun, Mar 16, 2014 at 01:50:10PM +0400, Alexander Chemeris wrote: > Hi Holger, > > It seems there are no more comments on this code. Could you please merge it? > It is independent of other changes. Hi! in Osmocom we prefer shorted/abbreviated names. Do you mind if we call it gsm340_gen_addr_field instead? This way some of the lines from the testcase get closer to 80 chars. holger From alexander.chemeris at gmail.com Thu Mar 27 05:14:26 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 27 Mar 2014 09:14:26 +0400 Subject: [PATCH] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). In-Reply-To: <20140326192222.GA769@xiaoyu.lan> References: <20140309182323.GA17965@xiaoyu.lan> <20140311142626.GH17965@xiaoyu.lan> <20140312123702.GD2460@xiaoyu.lan> <20140326192222.GA769@xiaoyu.lan> Message-ID: Holger, On Wed, Mar 26, 2014 at 11:22 PM, Holger Hans Peter Freyther wrote: > On Sun, Mar 16, 2014 at 01:50:10PM +0400, Alexander Chemeris wrote: >> Hi Holger, >> >> It seems there are no more comments on this code. Could you please merge it? >> It is independent of other changes. > > in Osmocom we prefer shorted/abbreviated names. Do you mind if we call > it gsm340_gen_addr_field instead? This way some of the lines from the > testcase get closer to 80 chars. Good idea. I'll update the patch during the next week. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. https://fairwaves.co From alexander.chemeris at gmail.com Sun Mar 9 10:58:04 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:58:04 +0100 Subject: [PATCH 3/6] sms: Rename gsm340_gen_tpdu() to gsm340_gen_sms_deliver_tpdu() to show that it generates SMS-DELIVER TPDU and is not a generic function. Message-ID: This is to prepare for the introduction of STATUS-REPORT messages. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-sms-Rename-gsm340_gen_tpdu-to-gsm340_gen_sms_deliver.patch Type: text/x-patch Size: 1671 bytes Desc: not available URL: From holger at freyther.de Sun Mar 9 18:32:49 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Mar 2014 19:32:49 +0100 Subject: [PATCH 3/6] sms: Rename gsm340_gen_tpdu() to gsm340_gen_sms_deliver_tpdu() to show that it generates SMS-DELIVER TPDU and is not a generic function. In-Reply-To: References: Message-ID: <20140309183249.GB17965@xiaoyu.lan> On Sun, Mar 09, 2014 at 11:58:04AM +0100, Alexander Chemeris wrote: > From e961b4f5fee04911b1c1f87d1b6aef496002ea8c Mon Sep 17 00:00:00 2001 > From: Alexander Chemeris > Date: Sat, 8 Mar 2014 23:54:28 +0100 > Subject: [PATCH 3/6] sms: Rename gsm340_gen_tpdu() to > gsm340_gen_sms_deliver_tpdu() to show that it generates > SMS-DELIVER TPDU and is not a generic function. man git-commit(1): "Though not required, it?s a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git. For example, git-format-patch(1) turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body." Please try to follow that. > +/* generate a msgb containing an 03.40 9.2.2.1 SMS-DELIVER TPDU derived from > + * struct gsm_sms, returns total size of TPDU */ Why "an"? Isn't "a" correct here? Document that < 0 indicates error? And the comment style is only for net/* ;) I have applied it anyway as the naming of the method appears to be a lot better. holger From alexander.chemeris at gmail.com Sun Mar 9 21:44:01 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 22:44:01 +0100 Subject: [PATCH 3/6] sms: Rename gsm340_gen_tpdu() to gsm340_gen_sms_deliver_tpdu() to show that it generates SMS-DELIVER TPDU and is not a generic function. In-Reply-To: <20140309183249.GB17965@xiaoyu.lan> References: <20140309183249.GB17965@xiaoyu.lan> Message-ID: On Sun, Mar 9, 2014 at 7:32 PM, Holger Hans Peter Freyther wrote: > On Sun, Mar 09, 2014 at 11:58:04AM +0100, Alexander Chemeris wrote: > >> From e961b4f5fee04911b1c1f87d1b6aef496002ea8c Mon Sep 17 00:00:00 2001 >> From: Alexander Chemeris >> Date: Sat, 8 Mar 2014 23:54:28 +0100 >> Subject: [PATCH 3/6] sms: Rename gsm340_gen_tpdu() to >> gsm340_gen_sms_deliver_tpdu() to show that it generates >> SMS-DELIVER TPDU and is not a generic function. > > man git-commit(1): > "Though not required, it?s a good idea to begin the commit message with > a single short (less than 50 character) line summarizing the change, > followed by a blank line and then a more thorough description. The text > up to the first blank line in a commit message is treated as the commit > title, and that title is used throughout Git. For example, > git-format-patch(1) turns a commit into email, and it uses the title on > the Subject line and the rest of the commit in the body." > > Please try to follow that. Yes, i try, sometimes I fail. >> +/* generate a msgb containing an 03.40 9.2.2.1 SMS-DELIVER TPDU derived from >> + * struct gsm_sms, returns total size of TPDU */ > > Why "an"? Isn't "a" correct here? You're probably right. Though this is not the biggest mistake with articles I did. > Document that < 0 indicates error? I'm improving step by step, focusing on most important changes first :) > And the comment style is only for net/* ;) Not sure I understand this comment? > I have applied it anyway as the naming of the method appears to be a > lot better. Thanks! -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From alexander.chemeris at gmail.com Sun Mar 9 10:58:55 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 11:58:55 +0100 Subject: [PATCH 4/6] sms: Send the actual TP-Service-Centre-Time-Stamp with SMS-DELIVER instead of a bogus current time. Message-ID: -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-sms-Send-the-actual-TP-Service-Centre-Time-Stamp-wit.patch Type: text/x-patch Size: 862 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 9 11:00:03 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 12:00:03 +0100 Subject: [PATCH 5/6] sms,db: Store SMS Message Reference in the DB, since we need it to generate SMS-STATUS-REPORT. Message-ID: 03.40 9.2.3.6TP-Message-Reference (TP-MR) The SMS-STATUS-REPORT also contains a TP-Message-Reference field. The value sent to the MS will be the sameas the TP-Message-Reference value generated by the MS in the earlier SMS-SUBMIT or SMS-COMMAND to whichthe status report relates. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-sms-db-Store-SMS-Message-Reference-in-the-DB-since-w.patch Type: text/x-patch Size: 3178 bytes Desc: not available URL: From alexander.chemeris at gmail.com Sun Mar 9 11:00:52 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Mar 2014 12:00:52 +0100 Subject: [PATCH 6/6] sms: Rename gsm340_gen_oa() to gsm340_gen_address_field(). Message-ID: Depends on the according patch for the libosmocore. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-sms-Rename-gsm340_gen_oa-to-gsm340_gen_address_field.patch Type: text/x-patch Size: 1489 bytes Desc: not available URL: From alexander.chemeris at gmail.com Mon Mar 10 19:22:00 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 10 Mar 2014 20:22:00 +0100 Subject: [PATCH] sms: Use gsm_7bit_decode_n() in sms_test(). Message-ID: gsm_7bit_decode() is deprecated. Replace it with gsm_7bit_decode_n(). The patch doesn't depend on anything and should be ready for merge into the master. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms-Use-gsm_7bit_decode_n-in-sms_test.patch Type: text/x-patch Size: 991 bytes Desc: not available URL: From holger at freyther.de Tue Mar 11 07:21:00 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Mar 2014 08:21:00 +0100 Subject: [PATCH] sms: Use gsm_7bit_decode_n() in sms_test(). In-Reply-To: References: Message-ID: <20140311072100.GY17965@xiaoyu.lan> On Mon, Mar 10, 2014 at 08:22:00PM +0100, Alexander Chemeris wrote: > gsm_7bit_decode() is deprecated. Replace it with gsm_7bit_decode_n(). > /* Test legacy function (return value only) */ > if (!test_decode[i].ud_hdr_ind) { > - nchars = gsm_7bit_decode(result, test_decode[i].input, > printf("Legacy decode case %d: " This test, tests the semantic of the old function. The only way this is going to be removed is by removing the legacy function. :) From alexander.chemeris at gmail.com Tue Mar 11 07:28:34 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 11 Mar 2014 11:28:34 +0400 Subject: [PATCH] sms: Use gsm_7bit_decode_n() in sms_test(). In-Reply-To: <20140311072100.GY17965@xiaoyu.lan> References: <20140311072100.GY17965@xiaoyu.lan> Message-ID: On Tue, Mar 11, 2014 at 11:21 AM, Holger Hans Peter Freyther wrote: > On Mon, Mar 10, 2014 at 08:22:00PM +0100, Alexander Chemeris wrote: > >> gsm_7bit_decode() is deprecated. Replace it with gsm_7bit_decode_n(). > >> /* Test legacy function (return value only) */ >> if (!test_decode[i].ud_hdr_ind) { >> - nchars = gsm_7bit_decode(result, test_decode[i].input, >> printf("Legacy decode case %d: " > > This test, tests the semantic of the old function. The only way this > is going to be removed is by removing the legacy function. :) Oh, right! I didn't realize it's a test for the deprecated function. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From anayuso at sysmocom.de Mon Mar 10 21:38:33 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Mon, 10 Mar 2014 22:38:33 +0100 Subject: [osmo-bts PATCH v2 1/2] misc/sysmobts_misc.c: Read temperature from microcontroller Message-ID: <20140310213615.6860.3924.stgit@Ph0enix> From: ?lvaro Neira Ayuso Add function for requesting the temperature information to the microcontroller. I have added a function that we can extend for requesting more information but in this case we only need to know the temperature. I have added to a microcontroller temperature handling function in the manager for monitoring this information. Signed-off-by: Alvaro Neira Ayuso --- v2: Removed and fixed the reanilization of the new timer, fixed the function write for consider the value 0 and fixed some leak in the new function for checking the temperature from the uc. src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 42 ++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 164 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 19 ++++ 3 files changed, 225 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 171f79b..cff15d9 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,44 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +static struct osmo_timer_list temp_uc_timer; +static void check_uctemp_timer_cb(void *data) +{ + int temp_pa = 0, temp_board = 0; + struct uc *ucontrol0 = data; + + sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); + + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); +} + +static void initialize_sbts2050(void) +{ + static struct uc ucontrol0 = { + .id = 0, + .path = "/dev/ttyS0" + }; + int val; + + ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); + if (ucontrol0.fd < 0) + return; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) + return; + + if (val == 2050) { + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) + return; + + if (val != 0) + return; + } + temp_uc_timer.cb = check_uctemp_timer_cb; + temp_uc_timer.data = &ucontrol0; + check_uctemp_timer_cb(&ucontrol0); +} + static struct osmo_timer_list temp_timer; static void check_temp_timer_cb(void *unused) { @@ -309,6 +348,9 @@ int main(int argc, char **argv) hours_timer.cb = hours_timer_cb; hours_timer_cb(NULL); + /* start uc temperature check timer */ + initialize_sbts2050(); + /* handle broadcast messages for ipaccess-find */ fd.cb = ipaccess_bcast; rc = osmo_sock_init_ofd(&fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index c043045..13957a4 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,170 @@ #include "sysmobts_misc.h" #include "sysmobts_par.h" #include "sysmobts_mgr.h" +#include "sbts2050_header.h" +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + +/********************************************************************** + * Functions read/write from serial interface + *********************************************************************/ +static int hand_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msgb_tailroom(msg)) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -1; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +static int hand_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc <= 0) + return -1; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + +/********************************************************************** + * Functions request information to Microcontroller + *********************************************************************/ +static void add_parity(cmdpkt_t *command) +{ + int n; + uint8_t parity = 0x00; + for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) + parity ^= ((uint8_t *)command)[n]; + + command->cmd.raw[command->u8Len] = parity; +} + +struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) +{ + int num, rc; + cmdpkt_t *command; + rsppkt_t *response; + struct msgb *msg; + fd_set fdread; + struct timeval tout = { + .tv_sec = 10, + }; + + switch (info.id) { + case SBTS2050_TEMP_RQT: + num = sizeof(command->cmd.tempGet); + break; + default: + return NULL; + } + num = num + SIZE_HEADER_CMD+1; + + msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + return NULL; + } + command = (cmdpkt_t *) msgb_put(msg, num); + + command->u16Magic = 0xCAFE; + switch (info.id) { + case SBTS2050_TEMP_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.tempGet); + break; + default: + goto err; + } + + add_parity(command); + + if (hand_serial_write(ucontrol->fd, msg) < 0) + goto err; + + msgb_reset(msg); + + FD_ZERO(&fdread); + FD_SET(ucontrol->fd, &fdread); + + num = SIZE_HEADER_RSP; + while (1) { + rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout); + if (rc > 0) { + if (hand_serial_read(ucontrol->fd, msg, num) < 0) + goto err; + + response = (rsppkt_t *)msg->data; + + if (response->u8Id != info.id || msg->len <= 0 || + response->i8Error != RQT_SUCCESS) + goto err; + + if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) + break; + + num = response->u8Len + 1; + } else + goto err; + } + + return msg; + +err: + close(ucontrol->fd); + msgb_free(msg); + return NULL; +} + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) +{ + rsppkt_t *response; + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_TEMP_RQT, + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); + return; + } + + response = (rsppkt_t *)msg->data; + + *temp_board = response->rsp.tempGet.i8BrdTemp; + *temp_pa = response->rsp.tempGet.i8PaTemp; + + LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" + "Tempeture PA: %+3d C\n", + response->rsp.tempGet.i8BrdTemp, + response->rsp.tempGet.i8PaTemp); + msgb_free(msg); +} /********************************************************************* * Temperature handling diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 8f7da47..bdaaaf7 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -1,6 +1,8 @@ #ifndef _SYSMOBTS_MISC_H #define _SYSMOBTS_MISC_H +#define RQT_SUCCESS 0 + enum sysmobts_temp_sensor { SYSMOBTS_TEMP_DIGITAL = 1, SYSMOBTS_TEMP_RF = 2, @@ -13,11 +15,28 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +struct uc { + int id; + int fd; + const char *path; +}; + +struct ucinfo { + uint16_t id; + int master; + int slave; + int pa; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); void sysmobts_check_temp(int no_eeprom_write); +struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info); + +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Mon Mar 10 21:43:48 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Mon, 10 Mar 2014 22:43:48 +0100 Subject: [osmo-bts PATCH v2 2/2] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <20140310213615.6860.3924.stgit@Ph0enix> References: <20140310213615.6860.3924.stgit@Ph0enix> Message-ID: <20140310213839.6860.56553.stgit@Ph0enix> From: ?lvaro Neira Ayuso I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And i have extended too with a function for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- v2: Fixed some leaks in the two new functions for requesting the status and for switching on and off the components src/osmo-bts-sysmo/misc/sysmobts_misc.c | 81 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 10 ++++ 2 files changed, 91 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 13957a4..6f849ed 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -114,6 +114,12 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -132,6 +138,17 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err; } @@ -176,6 +193,70 @@ err: } /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + return response->rsp.pwrGetStatus.u1MasterEn; + case SBTS2050_STATUS_SLAVE: + return response->rsp.pwrGetStatus.u1SlaveEn; + case SBTS2050_STATUS_PA: + return response->rsp.pwrGetStatus.u1PwrAmpEn; + default: + return -1; + } + msgb_free(msg); +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index bdaaaf7..cc8fbbc 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -15,6 +15,12 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; int fd; @@ -37,6 +43,10 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info); void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From koue at chaosophia.net Tue Mar 11 10:56:14 2014 From: koue at chaosophia.net (koue at chaosophia.net) Date: 11 Mar 2014 12:56:14 +0200 Subject: [PATCH] openbsc/tests/trau/Makefile.am Message-ID: [PATCH] openbsc/tests/trau/Makefile.am -------------- next part -------------- A non-text attachment was scrubbed... Name: patch-trau-Makefile.am.c Type: application/octet-stream Size: 491 bytes Desc: patch-trau-Makefile.am.c URL: From Max.Suraev at fairwaves.ru Tue Mar 11 11:05:06 2014 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Tue, 11 Mar 2014 12:05:06 +0100 Subject: patchwork question Message-ID: <531EEDE2.9080903@fairwaves.ru> Hi. There's no patches in http://patchwork.ozlabs.org/project/osmocom-bb/list/ and http://patchwork.ozlabs.org/project/openbsc/list/ - does it mean that system went online just recently or there's something wrong with the patches hanging in ML? -- best regards, Max, http://fairwaves.ru From holger at freyther.de Wed Mar 12 12:35:48 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 12 Mar 2014 13:35:48 +0100 Subject: patchwork question In-Reply-To: <531EEDE2.9080903@fairwaves.ru> References: <531EEDE2.9080903@fairwaves.ru> Message-ID: <20140312123548.GC2460@xiaoyu.lan> On Tue, Mar 11, 2014 at 12:05:06PM +0100, ? wrote: > Hi. > > There's no patches in http://patchwork.ozlabs.org/project/osmocom-bb/list/ and > http://patchwork.ozlabs.org/project/openbsc/list/ - does it mean that system went > online just recently or there's something wrong with the patches hanging in ML? The first three patches were on patchwork today. From anayuso at sysmocom.de Wed Mar 12 14:09:05 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Mar 2014 15:09:05 +0100 Subject: [osmo-bts PATCH v3 1/2] misc/sysmobts_misc.c: Read temperature from microcontroller Message-ID: <20140312135649.9518.84048.stgit@Ph0enix> From: ?lvaro Neira Ayuso Add function for requesting the temperature information to the microcontroller. I have added a function that we can extend for requesting more information but in this case we only need to know the temperature. I have added to a microcontroller temperature handling function in the manager for monitoring this information. Signed-off-by: Alvaro Neira Ayuso --- v3: Added check in the configure if the header exist. Fixed the initialization of the serial interface for doing after test if we are in a sbts2050. Removed the close descriptor in case of error in the request info function and added the function log for knowing the cause of the error. configure.ac | 4 + src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 52 ++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 163 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 17 +++ 4 files changed, 236 insertions(+) diff --git a/configure.ac b/configure.ac index 3411017..e52b38c 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,10 @@ AC_CHECK_HEADER([openbsc/gsm_data_shared.h],[], []) CPPFLAGS=$oldCPPFLAGS +# Check for the sbts2050_header.h that was added after the 3.6 release +AC_CHECK_HEADER([sysmocom/femtobts/sbts2050_header.h], + [echo "Found"], [echo "Not found"]) + AC_OUTPUT( src/Makefile src/common/Makefile diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 171f79b..3895d4e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,54 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +static struct osmo_timer_list temp_uc_timer; +static void check_uctemp_timer_cb(void *data) +{ + int temp_pa = 0, temp_board = 0; + struct uc *ucontrol0 = data; + + sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); + + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); +} + +static void initialize_sbts2050(void) +{ + static struct uc ucontrol0 = { + .id = 0, + .path = "/dev/ttyS0" + }; + int val; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to get Model number\n"); + return; + } + + if (val == 2050) { + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to get the TRX number\n"); + return; + } + + if (val != 0) + return; + } + + ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); + if (ucontrol0.fd < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to open the serial interface\n"); + return; + } + + temp_uc_timer.cb = check_uctemp_timer_cb; + temp_uc_timer.data = &ucontrol0; + check_uctemp_timer_cb(&ucontrol0); +} + static struct osmo_timer_list temp_timer; static void check_temp_timer_cb(void *unused) { @@ -309,6 +358,9 @@ int main(int argc, char **argv) hours_timer.cb = hours_timer_cb; hours_timer_cb(NULL); + /* start uc temperature check timer */ + initialize_sbts2050(); + /* handle broadcast messages for ipaccess-find */ fd.cb = ipaccess_bcast; rc = osmo_sock_init_ofd(&fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index c043045..081b65f 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,169 @@ #include "sysmobts_misc.h" #include "sysmobts_par.h" #include "sysmobts_mgr.h" +#include "sbts2050_header.h" +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + +/********************************************************************** + * Functions read/write from serial interface + *********************************************************************/ +static int hand_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msgb_tailroom(msg)) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -1; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +static int hand_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc <= 0) + return -1; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + +/********************************************************************** + * Functions request information to Microcontroller + *********************************************************************/ +static void add_parity(cmdpkt_t *command) +{ + int n; + uint8_t parity = 0x00; + for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) + parity ^= ((uint8_t *)command)[n]; + + command->cmd.raw[command->u8Len] = parity; +} + +struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) +{ + int num, rc; + cmdpkt_t *command; + rsppkt_t *response; + struct msgb *msg; + fd_set fdread; + struct timeval tout = { + .tv_sec = 10, + }; + + switch (info.id) { + case SBTS2050_TEMP_RQT: + num = sizeof(command->cmd.tempGet); + break; + default: + return NULL; + } + num = num + SIZE_HEADER_CMD+1; + + msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + return NULL; + } + command = (cmdpkt_t *) msgb_put(msg, num); + + command->u16Magic = 0xCAFE; + switch (info.id) { + case SBTS2050_TEMP_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.tempGet); + break; + default: + goto err; + } + + add_parity(command); + + if (hand_serial_write(ucontrol->fd, msg) < 0) + goto err; + + msgb_reset(msg); + + FD_ZERO(&fdread); + FD_SET(ucontrol->fd, &fdread); + + num = SIZE_HEADER_RSP; + while (1) { + rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout); + if (rc > 0) { + if (hand_serial_read(ucontrol->fd, msg, num) < 0) + goto err; + + response = (rsppkt_t *)msg->data; + + if (response->u8Id != info.id || msg->len <= 0 || + response->i8Error != RQT_SUCCESS) + goto err; + + if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) + break; + + num = response->u8Len + 1; + } else + goto err; + } + + return msg; + +err: + msgb_free(msg); + return NULL; +} + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) +{ + rsppkt_t *response; + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_TEMP_RQT, + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); + return; + } + + response = (rsppkt_t *)msg->data; + + *temp_board = response->rsp.tempGet.i8BrdTemp; + *temp_pa = response->rsp.tempGet.i8PaTemp; + + LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" + "Tempeture PA: %+3d C\n", + response->rsp.tempGet.i8BrdTemp, + response->rsp.tempGet.i8PaTemp); + msgb_free(msg); +} /********************************************************************* * Temperature handling diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 8f7da47..a0c57a4 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,11 +13,28 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +struct uc { + int id; + int fd; + const char *path; +}; + +struct ucinfo { + uint16_t id; + int master; + int slave; + int pa; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); void sysmobts_check_temp(int no_eeprom_write); +struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info); + +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Wed Mar 12 14:09:15 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Mar 2014 15:09:15 +0100 Subject: [osmo-bts PATCH v3 2/2] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <20140312135649.9518.84048.stgit@Ph0enix> References: <20140312135649.9518.84048.stgit@Ph0enix> Message-ID: <20140312140911.9518.60507.stgit@Ph0enix> From: ?lvaro Neira Ayuso I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And i have extended too with a function for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/misc/sysmobts_misc.c | 81 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 10 ++++ 2 files changed, 91 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 081b65f..310c681 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -114,6 +114,12 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -132,6 +138,17 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err; } @@ -175,6 +192,70 @@ err: } /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + return response->rsp.pwrGetStatus.u1MasterEn; + case SBTS2050_STATUS_SLAVE: + return response->rsp.pwrGetStatus.u1SlaveEn; + case SBTS2050_STATUS_PA: + return response->rsp.pwrGetStatus.u1PwrAmpEn; + default: + return -1; + } + msgb_free(msg); +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index a0c57a4..9967853 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,6 +13,12 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; int fd; @@ -35,6 +41,10 @@ struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info); void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Wed Mar 12 15:19:59 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Mar 2014 16:19:59 +0100 Subject: [osmo-bts PATCH v4] misc/sysmobts_misc.c: Read temperature from microcontroller Message-ID: <20140312151645.30964.44435.stgit@Ph0enix> From: ?lvaro Neira Ayuso Add function for requesting the temperature information to the microcontroller. I have added a function that we can extend for requesting more information but in this case we only need to know the temperature. I have added to a microcontroller temperature handling function in the manager for monitoring this information. Signed-off-by: Alvaro Neira Ayuso --- v4: Fixed the configure for considering if we are in a sbts2050 or not and compile the code that we will use. configure.ac | 10 ++ src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 56 ++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 172 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 15 +++ 4 files changed, 253 insertions(+) diff --git a/configure.ac b/configure.ac index 3411017..fa75274 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,16 @@ AC_CHECK_HEADER([openbsc/gsm_data_shared.h],[], []) CPPFLAGS=$oldCPPFLAGS +# Check for the sbts2050_header.h that was added after the 3.6 release +AC_CHECK_HEADER([sysmocom/femtobts/sbts2050_header.h], + [sysmo_uc_header="yes"],[]) + +if test "$sysmo_uc_header" = "yes" ; then + AC_DEFINE(BUILD_SBTS2050, 1, [Define if we want to build SBTS2050]) +fi +AM_CONDITIONAL(BUILD_SBTS2050, test "x$sysmo_uc_header" = "xyes") +AM_CONFIG_HEADER(btsconfig.h) + AC_OUTPUT( src/Makefile src/common/Makefile diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 171f79b..3a2c10c 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,58 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +#ifdef BUILD_SBTS2050 +static struct osmo_timer_list temp_uc_timer; +static void check_uctemp_timer_cb(void *data) +{ + int temp_pa = 0, temp_board = 0; + struct uc *ucontrol0 = data; + + sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); + + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); +} +#endif + +static void initialize_sbts2050(void) +{ +#ifdef BUILD_SBTS2050 + static struct uc ucontrol0 = { + .id = 0, + .path = "/dev/ttyS0" + }; + int val; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to get Model number\n"); + return; + } + + if (val == 2050) { + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to get the TRX number\n"); + return; + } + + if (val != 0) + return; + } + + ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); + if (ucontrol0.fd < 0) { + LOGP(DFIND, LOGL_ERROR, + "Failed to open the serial interface\n"); + return; + } + + temp_uc_timer.cb = check_uctemp_timer_cb; + temp_uc_timer.data = &ucontrol0; + check_uctemp_timer_cb(&ucontrol0); +#endif +} + static struct osmo_timer_list temp_timer; static void check_temp_timer_cb(void *unused) { @@ -309,6 +362,9 @@ int main(int argc, char **argv) hours_timer.cb = hours_timer_cb; hours_timer_cb(NULL); + /* start uc temperature check timer */ + initialize_sbts2050(); + /* handle broadcast messages for ipaccess-find */ fd.cb = ipaccess_bcast; rc = osmo_sock_init_ofd(&fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index c043045..55a7a2a 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -32,14 +32,186 @@ #include #include +#include #include #include #include +#include "btsconfig.h" #include "sysmobts_misc.h" #include "sysmobts_par.h" #include "sysmobts_mgr.h" +#ifdef BUILD_SBTS2050 +#include +#endif + +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + + +#ifdef BUILD_SBTS2050 +/********************************************************************** + * Functions read/write from serial interface + *********************************************************************/ +static int hand_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msgb_tailroom(msg)) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -1; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +static int hand_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc <= 0) + return -1; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + +/********************************************************************** + * Functions request information to Microcontroller + *********************************************************************/ +static void add_parity(cmdpkt_t *command) +{ + int n; + uint8_t parity = 0x00; + for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) + parity ^= ((uint8_t *)command)[n]; + + command->cmd.raw[command->u8Len] = parity; +} + +static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) +{ + int num, rc; + cmdpkt_t *command; + rsppkt_t *response; + struct msgb *msg; + fd_set fdread; + struct timeval tout = { + .tv_sec = 10, + }; + + switch (info.id) { + case SBTS2050_TEMP_RQT: + num = sizeof(command->cmd.tempGet); + break; + default: + return NULL; + } + num = num + SIZE_HEADER_CMD+1; + + msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + return NULL; + } + command = (cmdpkt_t *) msgb_put(msg, num); + + command->u16Magic = 0xCAFE; + switch (info.id) { + case SBTS2050_TEMP_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.tempGet); + break; + default: + goto err; + } + + add_parity(command); + + if (hand_serial_write(ucontrol->fd, msg) < 0) + goto err; + + msgb_reset(msg); + + FD_ZERO(&fdread); + FD_SET(ucontrol->fd, &fdread); + + num = SIZE_HEADER_RSP; + while (1) { + rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout); + if (rc > 0) { + if (hand_serial_read(ucontrol->fd, msg, num) < 0) + goto err; + + response = (rsppkt_t *)msg->data; + + if (response->u8Id != info.id || msg->len <= 0 || + response->i8Error != RQT_SUCCESS) + goto err; + + if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) + break; + + num = response->u8Len + 1; + } else + goto err; + } + + return msg; + +err: + msgb_free(msg); + return NULL; +} +#endif + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) +{ +#ifdef BUILD_SBTS2050 + rsppkt_t *response; + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_TEMP_RQT, + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); + return; + } + + response = (rsppkt_t *)msg->data; + + *temp_board = response->rsp.tempGet.i8BrdTemp; + *temp_pa = response->rsp.tempGet.i8PaTemp; + + LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" + "Tempeture PA: %+3d C\n", + response->rsp.tempGet.i8BrdTemp, + response->rsp.tempGet.i8PaTemp); + msgb_free(msg); +#endif +} /********************************************************************* * Temperature handling diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 8f7da47..3c6513e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,11 +13,26 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +struct uc { + int id; + int fd; + const char *path; +}; + +struct ucinfo { + uint16_t id; + int master; + int slave; + int pa; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); void sysmobts_check_temp(int no_eeprom_write); +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Wed Mar 12 15:39:27 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Mar 2014 16:39:27 +0100 Subject: [osmo-bts PATCH v4] misc/sysmobts_misc: function for switching off/on and requesting status power Message-ID: <20140312153450.31456.64913.stgit@Ph0enix> From: ?lvaro Neira Ayuso I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And i have extended too with a function for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- v4: Fixed the msgb_free in the function status. With the return, we never use it src/osmo-bts-sysmo/misc/sysmobts_misc.c | 81 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 10 ++++ 2 files changed, 91 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 55a7a2a..897d605 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -120,6 +120,12 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -138,6 +144,17 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err; } @@ -182,6 +199,70 @@ err: #endif /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + msgb_free(msg); + switch (status) { + case SBTS2050_STATUS_MASTER: + return response->rsp.pwrGetStatus.u1MasterEn; + case SBTS2050_STATUS_SLAVE: + return response->rsp.pwrGetStatus.u1SlaveEn; + case SBTS2050_STATUS_PA: + return response->rsp.pwrGetStatus.u1PwrAmpEn; + default: + return -1; + } +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 3c6513e..01878f2 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,6 +13,12 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; int fd; @@ -33,6 +39,10 @@ void sysmobts_check_temp(int no_eeprom_write); void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Wed Mar 12 17:15:28 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Wed, 12 Mar 2014 18:15:28 +0100 Subject: [osmo-bts PATCH v5] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <20140312153450.31456.64913.stgit@Ph0enix> References: <20140312153450.31456.64913.stgit@Ph0enix> Message-ID: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And I have extended it for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- v5: Fixed the switch in the status function, for freeing the msg. src/osmo-bts-sysmo/misc/sysmobts_misc.c | 87 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 10 ++++ 2 files changed, 97 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 55a7a2a..9ed528e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -120,6 +120,12 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -138,6 +144,17 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err; } @@ -182,6 +199,76 @@ err: #endif /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + int val_status; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + val_status = response->rsp.pwrGetStatus.u1MasterEn; + break; + case SBTS2050_STATUS_SLAVE: + val_status = response->rsp.pwrGetStatus.u1SlaveEn; + break; + case SBTS2050_STATUS_PA: + val_status = response->rsp.pwrGetStatus.u1PwrAmpEn; + break; + default: + msgb_free(msg); + return -1; + } + msgb_free(msg); + return val_status; +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 3c6513e..01878f2 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,6 +13,12 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; int fd; @@ -33,6 +39,10 @@ void sysmobts_check_temp(int no_eeprom_write); void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { -- 1.7.10.4 From holger at freyther.de Wed Mar 12 20:42:34 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 12 Mar 2014 21:42:34 +0100 Subject: [osmo-bts PATCH v5] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> References: <20140312153450.31456.64913.stgit@Ph0enix> <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> Message-ID: <20140312204234.GI2164@xiaoyu.lan> On Wed, Mar 12, 2014 at 06:15:28PM +0100, Alvaro Neira Ayuso wrote: > From: ?lvaro Neira Ayuso Dear Alvaro, > /********************************************************************** > + * Get power status function > + *********************************************************************/ > +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) I think you need to guard this with the BUILD_SBTS2050 define as well as I am getting a build error with the sbts2050 header not being installed. Please fix the build and re-submit (with in-reply-to). holger From anayuso at sysmocom.de Sat Mar 15 01:13:07 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Sat, 15 Mar 2014 02:13:07 +0100 Subject: [osmo-bts PATCH v6] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> References: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> Message-ID: <1394845987-21729-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And I have extended it for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- v6: Added the BUILD_SBTS2050 for fixing the error when we don't have the header. src/osmo-bts-sysmo/misc/sysmobts_misc.c | 93 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 10 ++++ 2 files changed, 103 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 55a7a2a..9ea26c2 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -120,6 +120,12 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -138,6 +144,17 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err; } @@ -182,6 +199,82 @@ err: #endif /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ +#ifdef BUILD_SBTS2050 + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + int val_status; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + val_status = response->rsp.pwrGetStatus.u1MasterEn; + break; + case SBTS2050_STATUS_SLAVE: + val_status = response->rsp.pwrGetStatus.u1SlaveEn; + break; + case SBTS2050_STATUS_PA: + val_status = response->rsp.pwrGetStatus.u1PwrAmpEn; + break; + default: + msgb_free(msg); + return -1; + } + msgb_free(msg); + return val_status; +#else + return -1; +#endif +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ +#ifdef BUILD_SBTS2050 + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +#endif +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 3c6513e..01878f2 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -13,6 +13,12 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; int fd; @@ -33,6 +39,10 @@ void sysmobts_check_temp(int no_eeprom_write); void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { -- 1.7.10.4 From peter at stuge.se Sat Mar 15 01:45:38 2014 From: peter at stuge.se (Peter Stuge) Date: Sat, 15 Mar 2014 02:45:38 +0100 Subject: [osmo-bts PATCH v6] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <1394845987-21729-1-git-send-email-anayuso@sysmocom.de> References: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> <1394845987-21729-1-git-send-email-anayuso@sysmocom.de> Message-ID: <20140315014538.10226.qmail@stuge.se> Alvaro Neira Ayuso wrote: > +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c > @@ -120,6 +120,12 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) > case SBTS2050_TEMP_RQT: > num = sizeof(command->cmd.tempGet); > break; > + case SBTS2050_PWR_RQT: > + num = sizeof(command->cmd.pwrSetState); > + break; A small style remark is that I like to use: sizeof command->cmd.pwerSetState since sizeof isn't really a function. Similar to return. > @@ -138,6 +144,17 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) > command->u8Id = info.id; > command->u8Len = sizeof(command->cmd.tempGet); > break; > + case SBTS2050_PWR_RQT: > + command->u8Id = info.id; > + command->u8Len = sizeof(command->cmd.pwrSetState); > + command->cmd.pwrSetState.u1MasterEn = !!info.master; > + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; > + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; > + break; > + case SBTS2050_PWR_STATUS: > + command->u8Id = info.id; > + command->u8Len = sizeof(command->cmd.pwrGetStatus); The above lines have a couple of extra spaces before the = which may or may not be worth fixing. > +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) .. > + msg = sbts2050_ucinfo_get(ucontrol, info); > + > + if (msg == NULL) { > + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); This error message doesn't contain very much information. It might be nice to know both which unit could not be switched off *and* what the error was. Also, is DTEMP guaranteed to always be the appropriate subsystem for this function? Maybe yes, but this code is in sysmobts_misc.c which suggests that it may be something more general? > +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h > @@ -13,6 +13,12 @@ enum sysmobts_temp_type { > _NUM_TEMP_TYPES > }; > > +enum sbts2050_status_rqt { > + SBTS2050_STATUS_MASTER, > + SBTS2050_STATUS_SLAVE, > + SBTS2050_STATUS_PA Maybe add a , after the last enum to make it easier to add more values in the future. //Peter From alvaroneay at gmail.com Sat Mar 15 02:10:06 2014 From: alvaroneay at gmail.com (=?ISO-8859-1?Q?=C1lvaro_Neira_Ayuso?=) Date: Sat, 15 Mar 2014 03:10:06 +0100 Subject: [osmo-bts PATCH v6] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <20140315014538.10226.qmail@stuge.se> References: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> <1394845987-21729-1-git-send-email-anayuso@sysmocom.de> <20140315014538.10226.qmail@stuge.se> Message-ID: <5323B67E.2040804@gmail.com> Hello Peter El 15/03/14 02:45, Peter Stuge escribi?: > Alvaro Neira Ayuso wrote: >> +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c >> @@ -120,6 +120,12 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) >> case SBTS2050_TEMP_RQT: >> num = sizeof(command->cmd.tempGet); >> break; >> + case SBTS2050_PWR_RQT: >> + num = sizeof(command->cmd.pwrSetState); >> + break; > > A small style remark is that I like to use: sizeof command->cmd.pwerSetState > since sizeof isn't really a function. Similar to return. I have followed the kernel coding style, and he said doesn't speak about use sizeof without bracket. > > >> @@ -138,6 +144,17 @@ static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) >> command->u8Id = info.id; >> command->u8Len = sizeof(command->cmd.tempGet); >> break; >> + case SBTS2050_PWR_RQT: >> + command->u8Id = info.id; >> + command->u8Len = sizeof(command->cmd.pwrSetState); >> + command->cmd.pwrSetState.u1MasterEn = !!info.master; >> + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; >> + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; >> + break; >> + case SBTS2050_PWR_STATUS: >> + command->u8Id = info.id; >> + command->u8Len = sizeof(command->cmd.pwrGetStatus); > > The above lines have a couple of extra spaces before the = which may > or may not be worth fixing. Yes, it's true, I don't know why I have done that... > > >> +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) > .. >> + msg = sbts2050_ucinfo_get(ucontrol, info); >> + >> + if (msg == NULL) { >> + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); > > This error message doesn't contain very much information. It might be > nice to know both which unit could not be switched off *and* what the > error was. > > Also, is DTEMP guaranteed to always be the appropriate subsystem for > this function? Maybe yes, but this code is in sysmobts_misc.c which > suggests that it may be something more general? I have used DTEMP, because i'm going to have a relation between the temperature and this function but it's true that somebody can use it in other cases. I don't know what do you think about that, if somebody can help me. > > >> +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h >> @@ -13,6 +13,12 @@ enum sysmobts_temp_type { >> _NUM_TEMP_TYPES >> }; >> >> +enum sbts2050_status_rqt { >> + SBTS2050_STATUS_MASTER, >> + SBTS2050_STATUS_SLAVE, >> + SBTS2050_STATUS_PA > > Maybe add a , after the last enum to make it easier to add more > values in the future. > > > //Peter > Thanks a lot Peter From peter at stuge.se Sat Mar 15 19:56:15 2014 From: peter at stuge.se (Peter Stuge) Date: Sat, 15 Mar 2014 20:56:15 +0100 Subject: [osmo-bts PATCH v6] misc/sysmobts_misc: function for switching off/on and requesting status power In-Reply-To: <5323B67E.2040804@gmail.com> References: <1394644528-31495-1-git-send-email-anayuso@sysmocom.de> <1394845987-21729-1-git-send-email-anayuso@sysmocom.de> <20140315014538.10226.qmail@stuge.se> <5323B67E.2040804@gmail.com> Message-ID: <20140315195615.2202.qmail@stuge.se> ?lvaro Neira Ayuso wrote: >>> + case SBTS2050_PWR_RQT: >>> + num = sizeof(command->cmd.pwrSetState); >>> + break; >> >> A small style remark is that I like to use: sizeof >> command->cmd.pwerSetState >> since sizeof isn't really a function. Similar to return. > > I have followed the kernel coding style, and he said doesn't speak about > use sizeof without bracket. All right! >>> +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt >>> status) >> .. >>> + msg = sbts2050_ucinfo_get(ucontrol, info); >>> + >>> + if (msg == NULL) { >>> + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); >> >> This error message doesn't contain very much information. It might be >> nice to know both which unit could not be switched off *and* what the >> error was. >> >> Also, is DTEMP guaranteed to always be the appropriate subsystem for >> this function? Maybe yes, but this code is in sysmobts_misc.c which >> suggests that it may be something more general? > > I have used DTEMP, because i'm going to have a relation between the > temperature and this function but it's true that somebody can use it in > other cases. I don't know what do you think about that, if somebody can > help me. I also don't know enough to make a suggestion here - it depends on how versatile these new sbts2050_uc_* functions should be. Maybe they are only intended to be called from the TEMP subsystem, then the current patch is fine. Hopefully someone with more overview can comment on this? //Peter From anayuso at sysmocom.de Wed Mar 12 17:35:37 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Mar 2014 18:35:37 +0100 Subject: [osmo-bts PATCH] misc/sysmobts_mgr: Added new header created in the configure Message-ID: <20140312173537.9256.20287.stgit@Ph0enix> From: ?lvaro Neira Ayuso Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 3a2c10c..6c64d0f 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -39,6 +39,7 @@ #include #include +#include "btsconfig.h" #include "misc/sysmobts_misc.h" #include "misc/sysmobts_mgr.h" #include "misc/sysmobts_nl.h" From Odd.Trandem at sintef.no Fri Mar 14 08:20:11 2014 From: Odd.Trandem at sintef.no (Odd Trandem) Date: Fri, 14 Mar 2014 08:20:11 +0000 Subject: ipaccess-telnet authentication problem Message-ID: <611C7371B2F0CC4CB3A04DFED07673D4A5AF8C86@SINTEFEXMBX04.sintef.no> Got a problem with ipacces-telnet. My goal is to run osmo-nitb, and do some experimenting. After a factory default reset, the following commands are given: (192.168.1.11 is ip-address of the nanoBTS) ./ipaccess-config 192.168.1.11 -u 1808/0/0 ./ipaccess-config 192.168.1.11 -o 192.168.1.1 ./ipaccess-config 192.168.1.11 -r (wait) ./ipaccess-config -n 0x400/0x400 192.168.1.11 Then I start ipaccess-telnet : ipaccess-telnet 192.168.1.11 3210 And I start osmo-ntib: osmo-nitb --config-file openbsc900.cfg ========================================================== The biggest problem, that makes debugging difficult, is that I after having run osmo-nitb, I cannot use ipaccess-telnet anymore. I have put in some additional prints into ip-access-auth.c to monitor the nanoBTS response: Two examples of OK response, before osmo-nitb is run: response: 3C 31 25 01 7C 3B B2 23 D6 7D 5D 84 17 62 9A 2E 9D 3E = "<1% |;?#?}]? b?.?>" (length = 18) response: 3C 76 B9 88 4C 43 D8 E3 1E 9A 2A 81 DD A0 C7 AC A5 3E = "" (length = 18) Two examples of response when nanoBTS refuse connection after having run osmo-nitb: response: 7B 58 0D 7C A4 50 75 83 2B FB 38 F2 66 AD B0 B6 AA 7D = {X?|?Pu?+?8?f????}" (length = 18) response: 7B 43 4A E6 5B A7 E2 1D 1C 8D F4 88 FF FB 26 F6 69 7D = "{CJ?[?? ?????&?i}" (length = 18) Only a factory default reset will make ipaccess-telnet working again. ========================================================== Output from osmo-nitb: <0019> input/ipaccess.c:945 enabling ipaccess BSC mode DB: Database initialized. DB: Database prepared. <001d> sms_queue.c:220 Attempting to send 20 SMS <0019> input/ipa.c:308 accept()ed new link from 192.168.1.11 to port 3002 <0019> input/ipaccess.c:422 Sign link vanished, dead socket <0019> input/ipaccess.c:260 Forcing socket shutdown with no signal link set <0019> input/ipa.c:308 accept()ed new link from 192.168.1.11 to port 3002 <0019> input/ipa.c:308 accept()ed new link from 192.168.1.11 to port 3003 <0004> bsc_init.c:265 bootstrapping RSL for BTS/TRX (0/0) on ARFCN 33 using MCC=1 MNC=1 LAC=1 CID=0 BSIC=63 TSC=7 Failure Event Report Type=processing failure Severity=warning level failure Probable cause= 03 00 01 Additional Text=40065:WARN:DHCP:dhcp_msg.c#692:Router Address not not valid: clearing it Failure Event Report Type=processing failure Severity=warning level failure Probable cause= 03 00 01 Additional Text=20233:WARN:DHCP:dhcp_msg.c#692:Router Address not not valid: clearing it ========================================================== Output from ipaccess-telnet: (NOT sure if this is exactly same run as shown in the osmo-nitb ouput) nanoBTS (c) ip.access Ltd 2001 30351:DBG:CLI_SKT:Remote client 192.168.1.1 connected 3525:DBG:TIB:OCXO is now WARM 4032:DBG:IP_CHANNEL:Assigning RX Client A 4032:DBG:IP_CHAN_RX_A:4711:ipChanConn: EVENT 0x00001742 rxd in STATE notconnected 4032:DBG:IP_CHAN_RX_A:Attempting connection to 192.168.1.1:3002 4033:DBG:IP_CHAN_RX_A:4712:ipChanConn: EVENT 0x00001741 rxd in STATE outgoingconnecting 6198:DBG:IP_CHAN_RX_A:4789:ipChanConn: EVENT 0x00001744 rxd in STATE outgoingconnecting 19151:DBG:DHCP:Event 4 received in State 3 19151:DBG:DHCP:T1 expired, sending Request 19154:DBG:DHCP:Tr Timer started with period 112 secs 19155:DBG:DHCP:Event 2 received in State 4 19155:DBG:DHCP:ACK received 19155:WARN:DHCP:dhcp_msg.c#696:Router Address not not valid: clearing it 19161:DBG:DB_EE:Writing 232 bytes of DBX data to block 3 19161:DBG:DB_EE:Re-using existing DBX block 19200:DBG:DB_EE:NV block 3 - wrote block to NV, main and backup OK. 19200:DBG:DB_EE:EE update complete. 28158:DBG:IP_CHANNEL:Assigning RX Client A 28158:DBG:IP_CHAN_RX_A:5541:ipChanConn: EVENT 0x00001742 rxd in STATE notconnected 28158:DBG:IP_CHAN_RX_A:Attempting connection to 192.168.1.1:3002 28158:DBG:IP_CHAN_RX_A:5542:ipChanConn: EVENT 0x00001747 rxd in STATE outgoingconnecting 28593:DBG:OAM_IM:Changing SYSTEM LINK from 0.0 to 73.255 28650:DBG:DB_EE:EE update complete. 29719:DBG:OAM_IM:Stopping "Primary OML Fallback Client" 29719:DBG:OAM_IM:Stopping "Secondary OML Server" 29719:DBG:OAM_IM:Not stopping "Secure Secondary OML Server" - has not been started 29719:DBG:OAM_IM:Not stopping "IML Site Server" - has not been started 29719:DBG:OAM_IM:Not stopping "Secure IML Site Server" - has not been started 29719:DBG:OAM_IM:Stopping "IML Bts Server" 29719:DBG:OAM_IM:Not stopping "Secure IML Bts Server" - has not been started 29719:DBG:OAM_IM:Stopping "IRL Patched Routing Link" 29719:DBG:OAM_IM:Failed to inject event=1="STOP" into link source (token=7) 29744:DBG:IP_CHAN_SERVER:Closed server listening on port 3006 29745:DBG:IP_CHAN_SERVER:Closed server listening on port 3014 29935:DBG:IP_CHAN_RX_A:5705:ipChanConn: EVENT 0x00001743 rxd in STATE connected 29935:DBG:IP_CHAN_RX_A:5706:ipChanConn: EVENT 0x00001741 rxd in STATE disconnectclosing ========================================================== Content of config file, openbsc900.cfg: ! ! OpenBSC configuration saved from vty ! ! password foo ! log stderr logging filter all 1 line vty no login ! e1_input e1_line 0 driver ipa network network country code 1 mobile network code 1 short name OpenBSC long name OpenBSC auth policy closed location updating reject cause 13 encryption a5 0 neci 1 rrlp mode none mm info 1 handover 0 handover window rxlev averaging 10 handover window rxqual averaging 1 handover window rxlev neighbor averaging 10 handover power budget interval 6 handover power budget hysteresis 3 handover maximum distance 9999 timer t3101 10 timer t3103 0 timer t3105 0 timer t3107 0 timer t3109 4 timer t3111 0 timer t3113 60 timer t3115 0 timer t3117 0 timer t3119 0 timer t3141 0 bts 0 type nanobts band DCS900 cell_identity 0 location_area_code 1 training_sequence_code 7 base_station_id_code 63 ms max power 15 cell reselection hysteresis 4 rxlev access min 0 channel allocator ascending rach tx integer 9 rach max transmission 7 ip.access unit_id 1808 0 oml ip.access stream_id 255 line 0 gprs mode none trx 0 rf_locked 0 arfcn 33 nominal power 23 max_power_red 20 rsl e1 tei 0 timeslot 0 phys_chan_config CCCH+SDCCH4 timeslot 1 phys_chan_config SDCCH8 timeslot 2 phys_chan_config TCH/F timeslot 3 phys_chan_config TCH/F timeslot 4 phys_chan_config TCH/F timeslot 5 phys_chan_config TCH/F timeslot 6 phys_chan_config TCH/F timeslot 7 phys_chan_config TCH/F Odd Trandem SINTEF ICT From holger at freyther.de Fri Mar 14 10:09:44 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 14 Mar 2014 11:09:44 +0100 Subject: ipaccess-telnet authentication problem In-Reply-To: <611C7371B2F0CC4CB3A04DFED07673D4A5AF8C86@SINTEFEXMBX04.sintef.no> References: <611C7371B2F0CC4CB3A04DFED07673D4A5AF8C86@SINTEFEXMBX04.sintef.no> Message-ID: <20140314100944.GN31238@xiaoyu.lan> On Fri, Mar 14, 2014 at 08:20:11AM +0000, Odd Trandem wrote: > Got a problem with ipacces-telnet. My goal is to run osmo-nitb, and do some experimenting. Hi, ip.access appears to have changed some parts of their authentication handling in newer firmware releases. I was told they broke the password less BTS Installer CLI interface too. In case you have a support contract with ip.access you might want to ask them of why they did that. At the same time I wonder if the GPRS reliability issues has been fixed. cheers holger From alexander.chemeris at gmail.com Sun Mar 16 11:14:21 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Mar 2014 15:14:21 +0400 Subject: [PATCH] sms_test: Use C99 initializers. Message-ID: Hi Holger, On Sun, Mar 16, 2014 at 1:55 PM, Holger Hans Peter Freyther wrote: > E.g. in one > of the testcases I noticed that you don't use C99 initializers but the > old/error prone way of initializing. :) Yes, I think in this particular case the old way is more compact and thus more readable. I added C99 initializers to the test (see the patch attached or achemeris/sms-fixes branch) and to me it looks less readable and thus more error prone. If you see any benefits of this patch - feel free to merge it, though. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-sms_test-Use-C99-initializers.patch Type: text/x-patch Size: 7513 bytes Desc: not available URL: From holger at freyther.de Thu Mar 20 21:24:40 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 22:24:40 +0100 Subject: [PATCH] sms_test: Use C99 initializers. In-Reply-To: References: Message-ID: <20140320212440.GB6455@xiaoyu.lan> On Sun, Mar 16, 2014 at 03:14:21PM +0400, Alexander Chemeris wrote: > I added C99 initializers to the test (see the patch attached or > achemeris/sms-fixes branch) and to me it looks less readable and thus > more error prone. If you see any benefits of this patch - feel free to > merge it, though. Can you squash the two patches and fix the typo in the subject line? The benefit of C99 is being a bit more robust against changes in the struct. From holger at freyther.de Sun Mar 16 13:27:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 16 Mar 2014 14:27:38 +0100 Subject: [PATCH] sysmobts: Add a magic number to the hLayer2 to differentiate it Message-ID: <1394976458-16342-1-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther The DSP/FPGA appears to report bogus PhDataInd with hlayer2 == 0. Currently this would match the TRX==0,TS==0 and SS=0 and then we report bad measurement reports. Add a magic number to the lower eight bit of the hLayer2 to differentiate valid numbers. Addresses: <0004> measurement.c:97 (bts=0,trx=0,ts=0,ss=0) measurement during state: NONE <0004> measurement.c:102 (bts=0,trx=0,ts=0,ss=0) no space for uplink measurement --- src/osmo-bts-sysmo/oml.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 596680f..7fcd4c6 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -704,17 +704,24 @@ err: uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan) { - return (lchan->nr << 8) | (lchan->ts->nr << 16) | (lchan->ts->trx->nr << 24); + return 0xBB + | (lchan->nr << 8) + | (lchan->ts->nr << 16) + | (lchan->ts->trx->nr << 24); } /* obtain a ptr to the lapdm_channel for a given hLayer */ struct gsm_lchan * l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2) { + uint8_t magic = hLayer2 & 0xff; uint8_t ts_nr = (hLayer2 >> 16) & 0xff; uint8_t lchan_nr = (hLayer2 >> 8)& 0xff; struct gsm_bts_trx_ts *ts; + if (magic != 0xBB) + return NULL; + /* FIXME: if we actually run on the BTS, the 32bit field is large * enough to simply put a pointer inside. */ if (ts_nr >= ARRAY_SIZE(trx->ts)) -- 1.9.0 From openbsc-bounces at lists.osmocom.org Mon Mar 17 07:00:17 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Mon, 17 Mar 2014 08:00:17 +0100 Subject: 2 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 2 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From openbsc-bounces at lists.osmocom.org Tue Mar 18 07:00:18 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Tue, 18 Mar 2014 08:00:18 +0100 Subject: 2 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 2 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From openbsc-bounces at lists.osmocom.org Wed Mar 19 07:00:18 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Wed, 19 Mar 2014 08:00:18 +0100 Subject: 2 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 2 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From openbsc-bounces at lists.osmocom.org Thu Mar 20 07:00:13 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Thu, 20 Mar 2014 08:00:13 +0100 Subject: 2 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 2 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From valtulina.luca at gmail.com Thu Mar 20 13:39:50 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Thu, 20 Mar 2014 14:39:50 +0100 Subject: Location Area Updates missed during calls Message-ID: Hi list, when a MS is in a call it misses the network-initiated Location Area Update procedure(s). This inconvenience can lead (if the call ends after the expire_lu time) to having an attached (and active) subscriber marked as expired in the HLR. Furthermore if at this point the MS initiates a new call, the call will be dropped and (as expected) a new Location Area Update procedure will be initiated by the BSC. I find this behavior annoying mostly in scenarios where the T3212 (LAU timer) has been setup to a low value. To tackle this issue I thought of triggering a subscriber update when a call get released (either by the network or by the MS) for each of the MS involved in the call. The code can also be optimized by checking whether the subscriber is expired before performing the update. I can provide a patch if you also consider the above as a misbehavior of OpenBSC. cheers luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Thu Mar 20 14:20:42 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Thu, 20 Mar 2014 15:20:42 +0100 Subject: Location Area Updates missed during calls In-Reply-To: References: Message-ID: <013401cf4447$950037e0$bf00a7a0$@schmid.xxx> Not exactly your issue, and mainly a testbed situation, nothing for the real world, but at least with OpenBTS I ran into similar issues when I stopped for some reason the BTS and restarted it immediately without keeping the TMSI assignment list. In this case the mobiles were not yet on extensive network search, so no registration attempts on other networks, registration flag still valid in the ME, no expired T3212. This leads to strange effects with GPRS and with incoming calls and short messages. I can imagine it may be similar with the openbsc family of BTSs. But as I have said, more an academic issue in lab tests, a real BTS runs all the time and is not restarted every few minutes :) Under what circumstances does the network initiate a LU procedure? Up to now I was not aware of this possibility. Ralph. From: openbsc-bounces at lists.osmocom.org [mailto:openbsc-bounces at lists.osmocom.org] On Behalf Of Luca Valtulina Sent: Thursday, March 20, 2014 2:40 PM To: openbsc at lists.osmocom.org Subject: Location Area Updates missed during calls Hi list, when a MS is in a call it misses the network-initiated Location Area Update procedure(s). This inconvenience can lead (if the call ends after the expire_lu time) to having an attached (and active) subscriber marked as expired in the HLR. Furthermore if at this point the MS initiates a new call, the call will be dropped and (as expected) a new Location Area Update procedure will be initiated by the BSC. I find this behavior annoying mostly in scenarios where the T3212 (LAU timer) has been setup to a low value. To tackle this issue I thought of triggering a subscriber update when a call get released (either by the network or by the MS) for each of the MS involved in the call. The code can also be optimized by checking whether the subscriber is expired before performing the update. I can provide a patch if you also consider the above as a misbehavior of OpenBSC. cheers luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Thu Mar 20 14:28:41 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 15:28:41 +0100 Subject: Location Area Updates missed during calls In-Reply-To: References: Message-ID: <20140320142841.GD10194@xiaoyu.lan> On Thu, Mar 20, 2014 at 02:39:50PM +0100, Luca Valtulina wrote: > Hi list, Dear Luca, > when a MS is in a call it misses the network-initiated Location Area Update > procedure(s). What is a network-initiated Location Area Update? Do you talk about the NITB/BSC advertizing periodic updating? > I find this behavior annoying mostly in scenarios where the T3212 (LAU > timer) has been setup to a low value. About which software and which versions do you talk? holger From valtulina.luca at gmail.com Fri Mar 21 10:10:53 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Fri, 21 Mar 2014 11:10:53 +0100 Subject: Fwd: Location Area Updates missed during calls In-Reply-To: References: <20140320142841.GD10194@xiaoyu.lan> Message-ID: Hi holger, What is a network-initiated Location Area Update? Do you talk about > the NITB/BSC advertizing periodic updating? With Location Area Update I refer to the Location Update procedure (I made confusion with the UMTS protocol where "Area" has been added in-between). I also have to apologies about that "network-initiated" which is clearly wrong since is the MS which triggers the procedure by sending a location update request signal (what I meant is that the T3212 timer is provided to the MS by the network). > > I find this behavior annoying mostly in scenarios where the T3212 (LAU > > timer) has been setup to a low value. > > About which software and which versions do you talk? mmm, I didn't quite get your question here. After performing further testing I can wrap up the issue as following: when a MS ends a call after the expire_lu time, it will be considered expired in the HLR (because two LUs were missed by the network). When the (now expired) MS initiates a call, the CM service will be rejected by the network with cause 4 (GSM48_REJECT_IMSI_UNKNOWN_IN_VLR). Needless to say that when a different MS tries to establish a call towards the (now expired) MS, this call will also be dropped because the destination MS is (seen as) detached from the BTS. Now I think that if we want to have a more precise location management, a lower expiration interval is a possibilities: this can be achieved by either lowering down the t3212 value and keeping the same expire_lu calculation (2 times t3212 + 1 minute) or by modifying the expire_lu calculation. In this scenarios the issue described above is more likely to happen (higher probability of having ~10 minutes calls than > 60 minutes). So indeed, is this behavior expected by the GSM protocol? I think that update the HLR whenever an MS exits a call will be a costless procedure which can avoid the annoyance of having the first next call dropped if this happens prior to the triggering of the LU by the interested MS. luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From valtulina.luca at gmail.com Fri Mar 21 16:17:12 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Fri, 21 Mar 2014 17:17:12 +0100 Subject: Location Area Updates missed during calls Message-ID: Indeed the problem has been already solved in the master branch by adding the "expire_timer_stopped" attributes to a gsm_subscriber_connection and then checking it upon expiration of the expire_lu timer for an active subscriber. Sorry to have re-raised the issue. luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From pablo at gnumonks.org Thu Mar 20 14:33:59 2014 From: pablo at gnumonks.org (pablo at gnumonks.org) Date: Thu, 20 Mar 2014 15:33:59 +0100 Subject: [PATCH 1/2 openggsn] gtp: fix wrong binary layout for struct gtp0_header in x86_64 Message-ID: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> From: Pablo Neira Ayuso struct gtp0_header needs __attribute__((packed)) to make sure that gcc doesn't add a hole of 4 bytes to align the 64-bits teid, resulting in 24 bytes instead of 20 bytes. This was breaking gtpv0 in my gprs testbed with my x86_64 laptop. While at it, add also attribute packed to other headers just to make sure that gcc doesn't pad the structures with holes. --- If no objections, I'll push this to master. gtp/gtp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtp/gtp.h b/gtp/gtp.h index 54af96e..39a902f 100644 --- a/gtp/gtp.h +++ b/gtp/gtp.h @@ -161,7 +161,7 @@ struct gtp0_header { /* Descriptions from 3GPP 09.60 */ uint8_t spare2; /* 11 Spare */ uint8_t spare3; /* 12 Spare */ uint64_t tid; /* 13 Tunnel ID */ -}; /* 20 */ +} __attribute__((packed)); /* 20 */ struct gtp1_header_short { /* Descriptions from 3GPP 29060 */ uint8_t flags; /* 01 bitfield, with typical values */ @@ -174,7 +174,7 @@ struct gtp1_header_short { /* Descriptions from 3GPP 29060 */ uint8_t type; /* 02 Message type. T-PDU = 0xff */ uint16_t length; /* 03 Length (of IP packet or signalling) */ uint32_t tei; /* 05 - 08 Tunnel Endpoint ID */ -}; +} __attribute__((packed)); struct gtp1_header_long { /* Descriptions from 3GPP 29060 */ uint8_t flags; /* 01 bitfield, with typical values */ @@ -190,7 +190,7 @@ struct gtp1_header_long { /* Descriptions from 3GPP 29060 */ uint16_t seq; /* 10 Sequence Number */ uint8_t npdu; /* 11 N-PDU Number */ uint8_t next; /* 12 Next extension header type. Empty = 0 */ -}; +} __attribute__((packed)); struct gtp0_packet { struct gtp0_header h; -- 1.7.10.4 From pablo at gnumonks.org Thu Mar 20 14:34:00 2014 From: pablo at gnumonks.org (pablo at gnumonks.org) Date: Thu, 20 Mar 2014 15:34:00 +0100 Subject: [PATCH 2/2 openggsn] gtp: fix endianness in teid field of GTPv0 header In-Reply-To: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> References: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> Message-ID: <1395326040-6285-2-git-send-email-pablo@gnumonks.org> From: Pablo Neira Ayuso This field needs to be in network byte order as well. --- The problem only shows up if you use sgsn and ggsn with different endianess. If no objections, I'll push this to master. gtp/gtp.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/gtp/gtp.c b/gtp/gtp.c index 3cc0c0b..fd4f0d0 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -250,7 +250,7 @@ static uint64_t get_tid(void *pack) union gtp_packet *packet = (union gtp_packet *)pack; if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */ - return packet->gtp0.h.tid; + return be64toh(packet->gtp0.h.tid); } return 0; } @@ -425,10 +425,11 @@ int gtp_req(struct gsn_t *gsn, int version, struct pdp_t *pdp, addr.sin_port = htons(GTP0_PORT); packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); packet->gtp0.h.seq = hton16(gsn->seq_next); - if (pdp) + if (pdp) { packet->gtp0.h.tid = - (pdp->imsi & 0x0fffffffffffffffull) + - ((uint64_t) pdp->nsapi << 60); + htobe64((pdp->imsi & 0x0fffffffffffffffull) + + ((uint64_t) pdp->nsapi << 60)); + } if (pdp && ((packet->gtp0.h.type == GTP_GPDU) || (packet->gtp0.h.type == GTP_ERROR))) packet->gtp0.h.flow = hton16(pdp->flru); @@ -581,7 +582,7 @@ int gtp_resp(int version, struct gsn_t *gsn, struct pdp_t *pdp, if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */ packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); packet->gtp0.h.seq = hton16(seq); - packet->gtp0.h.tid = tid; + packet->gtp0.h.tid = htobe64(tid); if (pdp && ((packet->gtp0.h.type == GTP_GPDU) || (packet->gtp0.h.type == GTP_ERROR))) packet->gtp0.h.flow = hton16(pdp->flru); @@ -1329,12 +1330,10 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version, memset(pdp, 0, sizeof(struct pdp_t)); if (version == 0) { - pdp->imsi = - ((union gtp_packet *)pack)->gtp0. - h.tid & 0x0fffffffffffffffull; - pdp->nsapi = - (((union gtp_packet *)pack)->gtp0. - h.tid & 0xf000000000000000ull) >> 60; + uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid); + + pdp->imsi = tid & 0x0fffffffffffffffull; + pdp->nsapi = (tid & 0xf000000000000000ull) >> 60; } pdp->seq = seq; @@ -2051,12 +2050,10 @@ int gtp_update_pdp_ind(struct gsn_t *gsn, int version, /* For GTP1 we must use imsi and nsapi if imsi is present. Otherwise */ /* we have to use the tunnel endpoint identifier */ if (version == 0) { - imsi = - ((union gtp_packet *)pack)->gtp0. - h.tid & 0x0fffffffffffffffull; - nsapi = - (((union gtp_packet *)pack)->gtp0. - h.tid & 0xf000000000000000ull) >> 60; + uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid); + + imsi = tid & 0x0fffffffffffffffull; + nsapi = (tid & 0xf000000000000000ull) >> 60; /* Find the context in question */ if (pdp_getimsi(&pdp, imsi, nsapi)) { @@ -2645,7 +2642,7 @@ int gtp_error_ind_conf(struct gsn_t *gsn, int version, struct pdp_t *pdp; /* Find the context in question */ - if (pdp_tidget(&pdp, ((union gtp_packet *)pack)->gtp0.h.tid)) { + if (pdp_tidget(&pdp, be64toh(((union gtp_packet *)pack)->gtp0.h.tid))) { gsn->err_unknownpdp++; gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len, "Unknown PDP context"); @@ -3197,8 +3194,8 @@ int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len) packet.gtp0.h.seq = hton16(pdp->gtpsntx++); packet.gtp0.h.flow = hton16(pdp->flru); packet.gtp0.h.tid = - (pdp->imsi & 0x0fffffffffffffffull) + - ((uint64_t) pdp->nsapi << 60); + htobe64((pdp->imsi & 0x0fffffffffffffffull) + + ((uint64_t) pdp->nsapi << 60)); if (len > sizeof(union gtp_packet) - sizeof(struct gtp0_header)) { gsn->err_memcpy++; -- 1.7.10.4 From holger at freyther.de Thu Mar 20 21:00:54 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 22:00:54 +0100 Subject: [PATCH 2/2 openggsn] gtp: fix endianness in teid field of GTPv0 header In-Reply-To: <1395326040-6285-2-git-send-email-pablo@gnumonks.org> References: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> <1395326040-6285-2-git-send-email-pablo@gnumonks.org> Message-ID: <20140320210054.GB2716@xiaoyu.lan> On Thu, Mar 20, 2014 at 03:34:00PM +0100, pablo at gnumonks.org wrote: > From: Pablo Neira Ayuso > > This field needs to be in network byte order as well. > --- > The problem only shows up if you use sgsn and ggsn with different > endianess. If no objections, I'll push this to master. Oh? Did you have a set-up where this actually happened? What do you think about having macros to "write" and "read" the tid/imsi/nsapi? From pablo at gnumonks.org Fri Mar 21 03:15:57 2014 From: pablo at gnumonks.org (Pablo Neira Ayuso) Date: Fri, 21 Mar 2014 04:15:57 +0100 Subject: [PATCH 2/2 openggsn] gtp: fix endianness in teid field of GTPv0 header In-Reply-To: <20140320210054.GB2716@xiaoyu.lan> References: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> <1395326040-6285-2-git-send-email-pablo@gnumonks.org> <20140320210054.GB2716@xiaoyu.lan> Message-ID: <20140321031557.GA11093@localhost> On Thu, Mar 20, 2014 at 10:00:54PM +0100, Holger Hans Peter Freyther wrote: > On Thu, Mar 20, 2014 at 03:34:00PM +0100, pablo at gnumonks.org wrote: > > From: Pablo Neira Ayuso > > > > This field needs to be in network byte order as well. > > --- > > The problem only shows up if you use sgsn and ggsn with different > > endianess. If no objections, I'll push this to master. > > Oh? Did you have a set-up where this actually happened? What do you > think about having macros to "write" and "read" the tid/imsi/nsapi? The problem also manifest with the gtp kernel module. Basically, the uplink packets from osmo-ggsn doesn't convert teid to network byte order. But downlink packets (going throught the gtp0 device) are indeed using network byte order. I'll add this to the description as well. And OK, I'll add some static inline functions to wrap that code. Thanks for the feedback. From holger at freyther.de Thu Mar 20 20:58:46 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 21:58:46 +0100 Subject: [PATCH 1/2 openggsn] gtp: fix wrong binary layout for struct gtp0_header in x86_64 In-Reply-To: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> References: <1395326040-6285-1-git-send-email-pablo@gnumonks.org> Message-ID: <20140320205846.GA2716@xiaoyu.lan> On Thu, Mar 20, 2014 at 03:33:59PM +0100, pablo at gnumonks.org wrote: > If no objections, I'll push this to master. please go ahead. it can't hurt. Thanks for trying out v0. From jerlbeck at sysmocom.de Thu Mar 20 18:14:33 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 20 Mar 2014 19:14:33 +0100 Subject: [PATCH 1/2] ipa/test: Add test program for IPA message reception Message-ID: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> This patch adds tests for ipa_msg_recv(), where messages are sent either complete or partitioned. Sponsored-by: On-Waves ehf --- tests/Makefile.am | 11 +- tests/ipa_recv/ipa_recv_test.c | 247 +++++++++++++++++++++++++++++++++++++++ tests/ipa_recv/ipa_recv_test.ok | 12 ++ tests/testsuite.at | 7 ++ 4 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 tests/ipa_recv/ipa_recv_test.c create mode 100644 tests/ipa_recv/ipa_recv_test.ok diff --git a/tests/Makefile.am b/tests/Makefile.am index af8a9cf..c8b8996 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,7 +5,8 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS) check_PROGRAMS = e1inp_ipa_bsc_test \ e1inp_ipa_bts_test \ ipa_proxy_test \ - subchan_demux/subchan_demux_test + subchan_demux/subchan_demux_test \ + ipa_recv/ipa_recv_test e1inp_ipa_bsc_test_SOURCES = e1inp_ipa_bsc_test.c e1inp_ipa_bsc_test_LDADD = $(top_builddir)/src/libosmoabis.la \ @@ -25,6 +26,11 @@ subchan_demux_subchan_demux_test_LDADD = $(top_builddir)/src/libosmoabis.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) +ipa_recv_ipa_recv_test_SOURCES = ipa_recv/ipa_recv_test.c +ipa_recv_ipa_recv_test_LDADD = $(top_builddir)/src/libosmoabis.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) + # boilerplate for the tests # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -45,7 +51,8 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac } >'$(srcdir)/package.m4' EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ - subchan_demux/subchan_demux_test.ok + subchan_demux/subchan_demux_test.ok \ + ipa_recv/ipa_recv_test.ok TESTSUITE = $(srcdir)/testsuite diff --git a/tests/ipa_recv/ipa_recv_test.c b/tests/ipa_recv/ipa_recv_test.c new file mode 100644 index 0000000..7b26259 --- /dev/null +++ b/tests/ipa_recv/ipa_recv_test.c @@ -0,0 +1,247 @@ +/* IPA receive test */ + +/* (C) 2014 by On-Waves + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if 0 +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_chanrqd[13] = { + 0x00, 0x0a, 0x00, 0x0c, 0x13, 0x01, 0x88, 0x13, + 0x4e, 0x42, 0x93, 0x11, 0x00 +}; + +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_chanactivack[10] = { + 0x00, 0x07, 0x00, 0x08, 0x22, 0x01, 0x12, 0x08, + 0x43, 0x81 +}; + +/* IPA protocol ip.access, type: RSL */ +static const unsigned char gsm_ipa_data[40] = { + 0x00, 0x25, 0x00, 0x08, 0x28, 0x01, 0x12, 0x1b, + 0x00, 0x19, 0x03, 0x3b, 0x3b, 0x00, 0x04, 0x00, + 0x0a, 0x38, 0x00, 0x0b, 0x00, 0x12, 0x06, 0x15, + 0x35, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + +static const char *ipa_test_messages[] = { + "Hello IPA", + "A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz", + "Hello again IPA", + "", + "Next is empty", + NULL, + "Bye", + "Bye", +}; + +static void append_ipa_message(struct msgb *msg, int proto, const char *text) +{ + int len = 0; + unsigned char *l2; + + if (text) + len = strlen(text) + 1; + + msgb_put_u16(msg, len); + msgb_put_u8(msg, proto); + + l2 = msgb_put(msg, len); + if (text) + strcpy((char *)l2, text); +} + +static int receive_messages(int fd) +{ + struct msgb *msg; + char dummy; + int rc; + while (1) { + if (recv(fd, &dummy, 1, MSG_PEEK) < 1) { + rc = -EAGAIN; + break; + } + msg = NULL; + rc = ipa_msg_recv(fd, &msg); + if (rc == -1) + rc = -errno; + fprintf(stderr, + "ipa_msg_recv: %d, msg %s NULL\n", + rc, msg ? "!=" : "=="); + if (rc == -EAGAIN) + printf( "got msg %s NULL, " + "returned: %s\n", + msg ? "!=" : "==", + rc == 0 ? "EOF" : + rc > 0 ? "OK" : + strerror(-rc)); + if (rc == 0) + return 0; + if (rc == -EAGAIN) + break; + if (rc < 0) { + printf("ipa_msg_recv failed with: %s\n", strerror(-rc)); + return rc; + } + printf("got IPA message, size=%d, proto=%d, text=\"%s\"\n", + rc, msg->data[2], msg->l2h); + msgb_free(msg); + }; + + return rc; +} + +static int slurp_data(int fd) { + int rc; + char buf[256]; + int count = 0; + + do { + rc = recv(fd, buf, sizeof(buf), 0); + if (rc <= 0) + break; + + count += rc; + } while (1); + + return count; +}; + +static void test_complete_recv(void) +{ + int sv[2]; + struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + int rc, i; + + printf("Testing IPA recv with complete messages.\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) + err(1, "socketpair"); + + fcntl(sv[0], F_SETFL, O_NONBLOCK); + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) + append_ipa_message(msg_out, 200, ipa_test_messages[i]); + + while (msg_out->len > 0) { + rc = write(sv[1], msg_out->data, msg_out->len); + if (rc == -1) + err(1, "write"); + msgb_pull(msg_out, rc); + } + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) { + rc = receive_messages(sv[0]); + if (rc == 0) + break; + + if (rc < 0 && rc != -EAGAIN) + break; + } + + rc = slurp_data(sv[0]); + printf("done: unread %d, unsent %d\n", rc, msg_out->len); + + close(sv[1]); + close(sv[0]); + + msgb_free(msg_out); +} + + +static void test_partial_recv(void) +{ + int sv[2]; + struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + int rc, i; + + printf("Testing IPA recv with partitioned messages.\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) + err(1, "socketpair"); + + fcntl(sv[0], F_SETFL, O_NONBLOCK); + + for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) + append_ipa_message(msg_out, 200, ipa_test_messages[i]); + + while (msg_out->len > 0) { + int len = 5; + if (len > msg_out->len) + len = msg_out->len; + if (write(sv[1], msg_out->data, len) == -1) + err(1, "write"); + msgb_pull(msg_out, len); + + if (msg_out->len == 0) + shutdown(sv[1], SHUT_WR); + + rc = receive_messages(sv[0]); + + if (rc == 0) + break; + + if (rc < 0 && rc != -EAGAIN) + break; + } + rc = slurp_data(sv[0]); + printf("done: unread %d, unsent %d\n", rc, msg_out->len); + + close(sv[1]); + close(sv[0]); + + msgb_free(msg_out); +} + +static struct log_info info = {}; + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + log_set_all_filter(osmo_stderr_target, 1); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + + printf("Testing the IPA layer.\n"); + + /* run the tests */ + test_complete_recv(); + test_partial_recv(); + + printf("No crashes.\n"); + return 0; +} diff --git a/tests/ipa_recv/ipa_recv_test.ok b/tests/ipa_recv/ipa_recv_test.ok new file mode 100644 index 0000000..4144d47 --- /dev/null +++ b/tests/ipa_recv/ipa_recv_test.ok @@ -0,0 +1,12 @@ +Testing the IPA layer. +Testing IPA recv with complete messages. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +done: unread 14, unsent 0 +Testing IPA recv with partitioned messages. +ipa_msg_recv failed with: Input/output error +done: unread 0, unsent 154 +No crashes. diff --git a/tests/testsuite.at b/tests/testsuite.at index 04193c5..ff550b0 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -11,8 +11,15 @@ AT_BANNER([Regression tests.]) # AT_CHECK([$abs_top_builddir/tests/NAME/NAME_test], [], [expout]) # AT_CLEANUP +AT_SETUP([ipa_recv]) +AT_KEYWORDS([ipa_recv]) +cat $abs_srcdir/ipa_recv/ipa_recv_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ipa_recv/ipa_recv_test], [], [expout],[ignore]) +AT_CLEANUP + AT_SETUP([subchan_demux]) AT_KEYWORDS([subchan_demux]) cat $abs_srcdir/subchan_demux/subchan_demux_test.ok > expout AT_CHECK([$abs_top_builddir/tests/subchan_demux/subchan_demux_test], [], [expout]) AT_CLEANUP + -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Mar 20 18:14:34 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 20 Mar 2014 19:14:34 +0100 Subject: [PATCH 2/2] ipa: Change ipa_msg_recv() to support partial receive In-Reply-To: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> Currently ipa_msg_recv() fails, when messages are received partially. This patch provides a new function ipa_msg_recv_buffered() that uses an additional ** to a message buffer to store partial data. When this happens, -EAGAIN is returned. If NULL is used, the function behaves similar to ipa_msg_recv() and fails on partial read. In addition iin case of errors the return value is now always -EXXX and the contents of errno is undefined. Note that this feature needs support by the calling code insofar that *tmp_msg must be set to NULL initially and it must be freed and set to NULL manually when the socket is closed. Note also that ipa_msg_recv() is then a wrapper around ipa_msg_recv_buffered() which mimics the old error behaviour by setting errno explicitely to -rc and returning -1 when an error has happened. Ticket: OW#728 Sponsored-by: On-Waves ehf --- include/osmocom/abis/e1_input.h | 2 + include/osmocom/abis/ipa.h | 3 + src/input/ipa.c | 151 ++++++++++++++++++++++++++++++--------- src/input/ipaccess.c | 13 +++- tests/ipa_recv/ipa_recv_test.c | 55 +++++++++----- tests/ipa_recv/ipa_recv_test.ok | 27 ++++++- 6 files changed, 197 insertions(+), 54 deletions(-) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 9b77893..cf8677b 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -109,6 +109,8 @@ struct e1inp_ts { struct osmo_fd fd; } rs232; } driver; + + struct msgb *pending_msg; }; struct gsm_e1_subslot { diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h index d577d74..982b694 100644 --- a/include/osmocom/abis/ipa.h +++ b/include/osmocom/abis/ipa.h @@ -27,6 +27,7 @@ struct ipa_server_conn { int (*closed_cb)(struct ipa_server_conn *peer); int (*cb)(struct ipa_server_conn *peer, struct msgb *msg); void *data; + struct msgb *pending_msg; }; struct ipa_server_conn *ipa_server_conn_create(void *ctx, struct ipa_server_link *link, int fd, int (*cb)(struct ipa_server_conn *peer, struct msgb *msg), int (*closed_cb)(struct ipa_server_conn *peer), void *data); @@ -53,6 +54,7 @@ struct ipa_client_conn { int (*read_cb)(struct ipa_client_conn *link, struct msgb *msg); int (*write_cb)(struct ipa_client_conn *link); void *data; + struct msgb *pending_msg; }; struct ipa_client_conn *ipa_client_conn_create(void *ctx, struct e1inp_ts *ts, int priv_nr, const char *addr, uint16_t port, void (*updown)(struct ipa_client_conn *link, int), int (*read_cb)(struct ipa_client_conn *link, struct msgb *msgb), int (*write_cb)(struct ipa_client_conn *link), void *data); @@ -64,6 +66,7 @@ void ipa_client_conn_close(struct ipa_client_conn *link); void ipa_client_conn_send(struct ipa_client_conn *link, struct msgb *msg); int ipa_msg_recv(int fd, struct msgb **rmsg); +int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg); int ipaccess_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd); diff --git a/src/input/ipa.c b/src/input/ipa.c index b5abd36..71e1227 100644 --- a/src/input/ipa.c +++ b/src/input/ipa.c @@ -49,50 +49,130 @@ void ipa_msg_push_header(struct msgb *msg, uint8_t proto) int ipa_msg_recv(int fd, struct msgb **rmsg) { - struct msgb *msg; + int rc = ipa_msg_recv_buffered(fd, rmsg, NULL); + if (rc < 0) { + errno = -rc; + rc = -1; + } + return rc; +} + +int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg) +{ + struct msgb *msg = tmp_msg ? *tmp_msg : NULL; struct ipaccess_head *hh; int len, ret; + int needed; - msg = ipa_msg_alloc(0); if (msg == NULL) - return -ENOMEM; + msg = ipa_msg_alloc(0); - /* first read our 3-byte header */ - hh = (struct ipaccess_head *) msg->data; - ret = recv(fd, msg->data, sizeof(*hh), 0); - if (ret <= 0) { - msgb_free(msg); - return ret; - } else if (ret != sizeof(*hh)) { - LOGP(DLINP, LOGL_ERROR, "too small message received\n"); - msgb_free(msg); - return -EIO; + if (msg == NULL) { + ret = -ENOMEM; + goto discard_msg; } - msgb_put(msg, ret); + + if (msg->l2h == NULL) { + /* first read our 3-byte header */ + needed = sizeof(*hh) - msg->len; + ret = recv(fd, msg->tail, needed, 0); + if (ret == 0) + goto discard_msg; + + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + ret = 0; + else { + ret = -errno; + goto discard_msg; + } + } + + msgb_put(msg, ret); + + if (ret < needed) { + if (msg->len == 0) { + ret = -EAGAIN; + goto discard_msg; + } + + LOGP(DLINP, LOGL_INFO, + "Received part of IPA message header (%d/%d)\n", + msg->len, sizeof(*hh)); + if (!tmp_msg) { + ret = -EIO; + goto discard_msg; + } + *tmp_msg = msg; + return -EAGAIN; + } + + msg->l2h = msg->tail; + } + + hh = (struct ipaccess_head *) msg->data; /* then read the length as specified in header */ - msg->l2h = msg->data + sizeof(*hh); len = ntohs(hh->len); if (len < 0 || IPA_ALLOC_SIZE < len + sizeof(*hh)) { LOGP(DLINP, LOGL_ERROR, "bad message length of %d bytes, " - "received %d bytes\n", len, ret); - msgb_free(msg); - return -EIO; + "received %d bytes\n", len, msg->len); + ret = -EIO; + goto discard_msg; } - ret = recv(fd, msg->l2h, len, 0); - if (ret <= 0) { - msgb_free(msg); - return ret; - } else if (ret < len) { - LOGP(DLINP, LOGL_ERROR, "truncated message received\n"); - msgb_free(msg); - return -EIO; + needed = len - msgb_l2len(msg); + + if (needed > 0) { + ret = recv(fd, msg->tail, needed, 0); + + if (ret == 0) + goto discard_msg; + + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + ret = 0; + else { + ret = -errno; + goto discard_msg; + } + } + + msgb_put(msg, ret); + + if (ret < needed) { + LOGP(DLINP, LOGL_INFO, + "Received part of IPA message L2 data (%d/%d)\n", + msgb_l2len(msg), len); + if (!tmp_msg) { + ret = -EIO; + goto discard_msg; + } + *tmp_msg = msg; + return -EAGAIN; + } } - msgb_put(msg, ret); + + ret = msgb_l2len(msg); + + if (ret == 0) { + LOGP(DLINP, LOGL_INFO, + "Discarding IPA message without payload\n"); + ret = -EAGAIN; + goto discard_msg; + } + + if (tmp_msg) + *tmp_msg = NULL; *rmsg = msg; return ret; + +discard_msg: + if (tmp_msg) + *tmp_msg = NULL; + msgb_free(msg); + return ret; } void ipa_client_conn_close(struct ipa_client_conn *link) @@ -103,6 +183,8 @@ void ipa_client_conn_close(struct ipa_client_conn *link) close(link->ofd->fd); link->ofd->fd = -1; } + msgb_free(link->pending_msg); + link->pending_msg = NULL; } static void ipa_client_read(struct ipa_client_conn *link) @@ -113,11 +195,12 @@ static void ipa_client_read(struct ipa_client_conn *link) LOGP(DLINP, LOGL_DEBUG, "message received\n"); - ret = ipa_msg_recv(ofd->fd, &msg); + ret = ipa_msg_recv_buffered(ofd->fd, &msg, &link->pending_msg); if (ret < 0) { - if (errno == EPIPE || errno == ECONNRESET) { + if (ret == -EAGAIN) + return; + if (ret == -EPIPE || ret == -ECONNRESET) LOGP(DLINP, LOGL_ERROR, "lost connection with server\n"); - } ipa_client_conn_close(link); if (link->updown_cb) link->updown_cb(link, 0); @@ -382,11 +465,12 @@ static void ipa_server_conn_read(struct ipa_server_conn *conn) LOGP(DLINP, LOGL_DEBUG, "message received\n"); - ret = ipa_msg_recv(ofd->fd, &msg); + ret = ipa_msg_recv_buffered(ofd->fd, &msg, &conn->pending_msg); if (ret < 0) { - if (errno == EPIPE || errno == ECONNRESET) { + if (ret == -EAGAIN) + return; + if (ret == -EPIPE || ret == -ECONNRESET) LOGP(DLINP, LOGL_ERROR, "lost connection with server\n"); - } ipa_server_conn_destroy(conn); return; } else if (ret == 0) { @@ -471,6 +555,7 @@ ipa_server_conn_create(void *ctx, struct ipa_server_link *link, int fd, void ipa_server_conn_destroy(struct ipa_server_conn *conn) { close(conn->ofd.fd); + msgb_free(conn->pending_msg); osmo_fd_unregister(&conn->ofd); if (conn->closed_cb) conn->closed_cb(conn); diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 225d70c..92ad619 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -258,6 +258,8 @@ int ipaccess_rcvmsg_bts_base(struct msgb *msg, static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line) { int ret = 1; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; /* Error case: we did not see any ID_RESP yet for this socket. */ if (bfd->fd != -1) { @@ -269,6 +271,9 @@ static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line) ret = -ENOENT; } + msgb_free(e1i_ts->pending_msg); + e1i_ts->pending_msg = NULL; + /* e1inp_sign_link_destroy releases the socket descriptors for us. */ line->ops->sign_link_down(line); @@ -415,13 +420,15 @@ static int handle_ts1_read(struct osmo_fd *bfd) struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; struct e1inp_sign_link *link; struct ipaccess_head *hh; - struct msgb *msg; + struct msgb *msg = NULL; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &e1i_ts->pending_msg); if (ret < 0) { + if (ret == -EAGAIN) + return; LOGP(DLINP, LOGL_NOTICE, "Sign link problems, " - "closing socket. Reason: %s\n", strerror(errno)); + "closing socket. Reason: %s\n", strerror(-ret)); goto err; } else if (ret == 0) { LOGP(DLINP, LOGL_NOTICE, "Sign link vanished, dead socket\n"); diff --git a/tests/ipa_recv/ipa_recv_test.c b/tests/ipa_recv/ipa_recv_test.c index 7b26259..8cdc7e2 100644 --- a/tests/ipa_recv/ipa_recv_test.c +++ b/tests/ipa_recv/ipa_recv_test.c @@ -86,7 +86,7 @@ static void append_ipa_message(struct msgb *msg, int proto, const char *text) strcpy((char *)l2, text); } -static int receive_messages(int fd) +static int receive_messages(int fd, struct msgb **pending_msg) { struct msgb *msg; char dummy; @@ -97,13 +97,22 @@ static int receive_messages(int fd) break; } msg = NULL; - rc = ipa_msg_recv(fd, &msg); - if (rc == -1) - rc = -errno; + rc = ipa_msg_recv_buffered(fd, &msg, pending_msg); + fprintf(stderr, - "ipa_msg_recv: %d, msg %s NULL\n", - rc, msg ? "!=" : "=="); - if (rc == -EAGAIN) + "ipa_msg_recv_buffered: %d, msg %s NULL, " + "pending_msg %s NULL\n", + rc, msg ? "!=" : "==", + !pending_msg ? "??" : *pending_msg ? "!=" : "=="); + if (pending_msg && !!msg == !!*pending_msg) + printf( "got msg %s NULL, pending_msg %s NULL, " + "returned: %s\n", + msg ? "!=" : "==", + *pending_msg ? "!=" : "==", + rc == 0 ? "EOF" : + rc > 0 ? "OK" : + strerror(-rc)); + else if (!pending_msg && rc == -EAGAIN) printf( "got msg %s NULL, " "returned: %s\n", msg ? "!=" : "==", @@ -115,7 +124,8 @@ static int receive_messages(int fd) if (rc == -EAGAIN) break; if (rc < 0) { - printf("ipa_msg_recv failed with: %s\n", strerror(-rc)); + printf("ipa_msg_recv_buffered failed with: %s\n", + strerror(-rc)); return rc; } printf("got IPA message, size=%d, proto=%d, text=\"%s\"\n", @@ -142,13 +152,15 @@ static int slurp_data(int fd) { return count; }; -static void test_complete_recv(void) +static void test_complete_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with complete messages.\n"); + printf("Testing IPA recv with complete messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -166,7 +178,11 @@ static void test_complete_recv(void) } for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) { - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); + if (pending_msg) + printf("Unexpected partial message: size=%d\n", + pending_msg->len); if (rc == 0) break; @@ -181,16 +197,19 @@ static void test_complete_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } -static void test_partial_recv(void) +static void test_partial_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with partitioned messages.\n"); + printf("Testing IPA recv with partitioned messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -211,7 +230,8 @@ static void test_partial_recv(void) if (msg_out->len == 0) shutdown(sv[1], SHUT_WR); - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); if (rc == 0) break; @@ -226,6 +246,7 @@ static void test_partial_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } static struct log_info info = {}; @@ -239,8 +260,10 @@ int main(int argc, char **argv) printf("Testing the IPA layer.\n"); /* run the tests */ - test_complete_recv(); - test_partial_recv(); + test_complete_recv(1); + test_partial_recv(1); + test_complete_recv(0); + test_partial_recv(0); printf("No crashes.\n"); return 0; diff --git a/tests/ipa_recv/ipa_recv_test.ok b/tests/ipa_recv/ipa_recv_test.ok index 4144d47..bdbfb7d 100644 --- a/tests/ipa_recv/ipa_recv_test.ok +++ b/tests/ipa_recv/ipa_recv_test.ok @@ -5,8 +5,31 @@ got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMN got IPA message, size=16, proto=200, text="Hello again IPA" got IPA message, size=1, proto=200, text="" got IPA message, size=14, proto=200, text="Next is empty" -done: unread 14, unsent 0 +got msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 Testing IPA recv with partitioned messages. -ipa_msg_recv failed with: Input/output error +ipa_msg_recv_buffered failed with: Input/output error done: unread 0, unsent 154 +Testing IPA recv with complete messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 +Testing IPA recv with partitioned messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 No crashes. -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Mar 20 18:26:36 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 20 Mar 2014 19:26:36 +0100 Subject: [PATCH] ipa: Use enhanced ipa_msg_recv_buffered() to cope with partioned IPA messages In-Reply-To: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1395339996-5962-1-git-send-email-jerlbeck@sysmocom.de> The old ipa_msg_recv() implementation didn't support partial receive, so IPA connections got disconnected when this happened. This patch adds the handling of the temporary message buffers and uses ipa_msg_recv_buffered(). It has been successfully tested by jerlbeck with osmo-nitb and osmo-bsc. Ticket: OW#768 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/bsc_msc.h | 2 ++ openbsc/include/openbsc/bsc_nat.h | 5 +++++ openbsc/include/openbsc/control_cmd.h | 3 +++ openbsc/src/libbsc/bsc_msc.c | 10 ++++++++++ openbsc/src/libctrl/control_if.c | 5 ++++- openbsc/src/osmo-bsc/osmo_bsc_msc.c | 6 ++++-- openbsc/src/osmo-bsc_nat/bsc_nat.c | 19 +++++++++++++++---- openbsc/src/osmo-bsc_nat/bsc_ussd.c | 8 ++++++-- 8 files changed, 49 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h index 647f47e..0adbd26 100644 --- a/openbsc/include/openbsc/bsc_msc.h +++ b/openbsc/include/openbsc/bsc_msc.h @@ -48,6 +48,8 @@ struct bsc_msc_connection { void (*connected) (struct bsc_msc_connection *); struct osmo_timer_list reconnect_timer; struct osmo_timer_list timeout_timer; + + struct msgb *pending_msg; }; struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest); diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index fe8e521..7bd582c 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -97,6 +97,9 @@ struct bsc_connection { /* the fd we use to communicate */ struct osmo_wqueue write_queue; + /* incoming message buffer */ + struct msgb *pending_msg; + /* the BSS associated */ struct bsc_config *cfg; @@ -343,6 +346,8 @@ struct bsc_nat_ussd_con { struct bsc_nat *nat; int authorized; + struct msgb *pending_msg; + struct osmo_timer_list auth_timeout; }; diff --git a/openbsc/include/openbsc/control_cmd.h b/openbsc/include/openbsc/control_cmd.h index cd7b7b6..1217375 100644 --- a/openbsc/include/openbsc/control_cmd.h +++ b/openbsc/include/openbsc/control_cmd.h @@ -39,6 +39,9 @@ struct ctrl_connection { /* The queue for sending data back */ struct osmo_wqueue write_queue; + /* Buffer for partial input data */ + struct msgb *pending_msg; + /* Callback if the connection was closed */ void (*closed_cb)(struct ctrl_connection *conn); diff --git a/openbsc/src/libbsc/bsc_msc.c b/openbsc/src/libbsc/bsc_msc.c index 1a0f78a..a24efab 100644 --- a/openbsc/src/libbsc/bsc_msc.c +++ b/openbsc/src/libbsc/bsc_msc.c @@ -42,6 +42,13 @@ static void connection_loss(struct bsc_msc_connection *con) fd = &con->write_queue.bfd; + if (con->pending_msg) { + LOGP(DMSC, LOGL_ERROR, + "MSC(%s) dropping incomplete message.\n", con->name); + msgb_free(con->pending_msg); + con->pending_msg = NULL; + } + close(fd->fd); fd->fd = -1; fd->cb = osmo_wqueue_bfd_cb; @@ -162,6 +169,9 @@ int bsc_msc_connect(struct bsc_msc_connection *con) con->is_connected = 0; + msgb_free(con->pending_msg); + con->pending_msg = NULL; + fd = &con->write_queue.bfd; fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); fd->priv_nr = 1; diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c index b5db31d..1bacd31 100644 --- a/openbsc/src/libctrl/control_if.c +++ b/openbsc/src/libctrl/control_if.c @@ -270,6 +270,7 @@ static void control_close_conn(struct ctrl_connection *ccon) llist_del(&ccon->list_entry); if (ccon->closed_cb) ccon->closed_cb(ccon); + msgb_free(ccon->pending_msg); talloc_free(ccon); } @@ -287,8 +288,10 @@ static int handle_control_read(struct osmo_fd * bfd) queue = container_of(bfd, struct osmo_wqueue, bfd); ccon = container_of(queue, struct ctrl_connection, write_queue); - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &ccon->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n"); else diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c index 5517d30..3d29c60 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c @@ -246,13 +246,15 @@ static void osmo_ext_handle(struct osmo_msc_data *msc, struct msgb *msg) static int ipaccess_a_fd_cb(struct osmo_fd *bfd) { - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct osmo_msc_data *data = (struct osmo_msc_data *) bfd->data; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &data->msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) { LOGP(DMSC, LOGL_ERROR, "The connection to the MSC was lost.\n"); bsc_msc_lost(data->msc_con); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index d9fc0ca..524186a 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -796,14 +796,16 @@ static void msc_send_reset(struct bsc_msc_connection *msc_con) static int ipaccess_msc_read_cb(struct osmo_fd *bfd) { struct bsc_msc_connection *msc_con; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; msc_con = (struct bsc_msc_connection *) bfd->data; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_FATAL, "The connection the MSC(%s) was lost, exiting\n", @@ -912,6 +914,13 @@ void bsc_close_connection(struct bsc_connection *connection) osmo_wqueue_clear(&connection->write_queue); llist_del(&connection->list_entry); + if (connection->pending_msg) { + LOGP(DNAT, LOGL_ERROR, "Dropping partial message on connection %d.\n", + connection->cfg->nr); + msgb_free(connection->pending_msg); + connection->pending_msg = NULL; + } + talloc_free(connection); } @@ -1206,13 +1215,15 @@ exit3: static int ipaccess_bsc_read_cb(struct osmo_fd *bfd) { struct bsc_connection *bsc = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct ipaccess_head_ext *hh_ext; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &bsc->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_ERROR, "The connection to the BSC Nr: %d was lost. Cleaning it\n", diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index 8da8181..5f073bf 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -66,6 +66,8 @@ static void bsc_nat_ussd_destroy(struct bsc_nat_ussd_con *con) osmo_fd_unregister(&con->queue.bfd); osmo_timer_del(&con->auth_timeout); osmo_wqueue_clear(&con->queue); + + msgb_free(con->pending_msg); talloc_free(con); } @@ -117,12 +119,14 @@ static int forward_sccp(struct bsc_nat *nat, struct msgb *msg) static int ussd_read_cb(struct osmo_fd *bfd) { struct bsc_nat_ussd_con *conn = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &conn->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n"); bsc_nat_ussd_destroy(conn); return -1; -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Mar 31 11:42:11 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 31 Mar 2014 13:42:11 +0200 Subject: [PATCH] ipa: Use enhanced ipa_msg_recv_buffered() to cope with partioned IPA messages In-Reply-To: <1395339996-5962-1-git-send-email-jerlbeck@sysmocom.de> References: <1395339996-5962-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1396266131-31083-1-git-send-email-jerlbeck@sysmocom.de> The old ipa_msg_recv() implementation didn't support partial receive, so IPA connections got disconnected when this happened. This patch adds the handling of the temporary message buffers and uses ipa_msg_recv_buffered(). It has been successfully tested by jerlbeck with osmo-nitb and osmo-bsc. Ticket: OW#768 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/bsc_msc.h | 2 ++ openbsc/include/openbsc/bsc_nat.h | 5 +++++ openbsc/include/openbsc/control_cmd.h | 3 +++ openbsc/src/libbsc/bsc_msc.c | 10 ++++++++++ openbsc/src/libctrl/control_if.c | 5 ++++- openbsc/src/osmo-bsc/osmo_bsc_msc.c | 6 ++++-- openbsc/src/osmo-bsc_nat/bsc_nat.c | 19 +++++++++++++++---- openbsc/src/osmo-bsc_nat/bsc_ussd.c | 8 ++++++-- 8 files changed, 49 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h index 647f47e..0adbd26 100644 --- a/openbsc/include/openbsc/bsc_msc.h +++ b/openbsc/include/openbsc/bsc_msc.h @@ -48,6 +48,8 @@ struct bsc_msc_connection { void (*connected) (struct bsc_msc_connection *); struct osmo_timer_list reconnect_timer; struct osmo_timer_list timeout_timer; + + struct msgb *pending_msg; }; struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest); diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index fe8e521..7bd582c 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -97,6 +97,9 @@ struct bsc_connection { /* the fd we use to communicate */ struct osmo_wqueue write_queue; + /* incoming message buffer */ + struct msgb *pending_msg; + /* the BSS associated */ struct bsc_config *cfg; @@ -343,6 +346,8 @@ struct bsc_nat_ussd_con { struct bsc_nat *nat; int authorized; + struct msgb *pending_msg; + struct osmo_timer_list auth_timeout; }; diff --git a/openbsc/include/openbsc/control_cmd.h b/openbsc/include/openbsc/control_cmd.h index 725dce0..8aede15 100644 --- a/openbsc/include/openbsc/control_cmd.h +++ b/openbsc/include/openbsc/control_cmd.h @@ -39,6 +39,9 @@ struct ctrl_connection { /* The queue for sending data back */ struct osmo_wqueue write_queue; + /* Buffer for partial input data */ + struct msgb *pending_msg; + /* Callback if the connection was closed */ void (*closed_cb)(struct ctrl_connection *conn); diff --git a/openbsc/src/libbsc/bsc_msc.c b/openbsc/src/libbsc/bsc_msc.c index 1a0f78a..a24efab 100644 --- a/openbsc/src/libbsc/bsc_msc.c +++ b/openbsc/src/libbsc/bsc_msc.c @@ -42,6 +42,13 @@ static void connection_loss(struct bsc_msc_connection *con) fd = &con->write_queue.bfd; + if (con->pending_msg) { + LOGP(DMSC, LOGL_ERROR, + "MSC(%s) dropping incomplete message.\n", con->name); + msgb_free(con->pending_msg); + con->pending_msg = NULL; + } + close(fd->fd); fd->fd = -1; fd->cb = osmo_wqueue_bfd_cb; @@ -162,6 +169,9 @@ int bsc_msc_connect(struct bsc_msc_connection *con) con->is_connected = 0; + msgb_free(con->pending_msg); + con->pending_msg = NULL; + fd = &con->write_queue.bfd; fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); fd->priv_nr = 1; diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c index 2727d0d..ca59d8c 100644 --- a/openbsc/src/libctrl/control_if.c +++ b/openbsc/src/libctrl/control_if.c @@ -123,6 +123,7 @@ static void control_close_conn(struct ctrl_connection *ccon) llist_del(&ccon->list_entry); if (ccon->closed_cb) ccon->closed_cb(ccon); + msgb_free(ccon->pending_msg); talloc_free(ccon); } @@ -140,8 +141,10 @@ static int handle_control_read(struct osmo_fd * bfd) queue = container_of(bfd, struct osmo_wqueue, bfd); ccon = container_of(queue, struct ctrl_connection, write_queue); - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &ccon->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n"); else diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c index 6033985..04e9cf3 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c @@ -247,13 +247,15 @@ static void osmo_ext_handle(struct osmo_msc_data *msc, struct msgb *msg) static int ipaccess_a_fd_cb(struct osmo_fd *bfd) { - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct osmo_msc_data *data = (struct osmo_msc_data *) bfd->data; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &data->msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) { LOGP(DMSC, LOGL_ERROR, "The connection to the MSC was lost.\n"); bsc_msc_lost(data->msc_con); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index d9fc0ca..524186a 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -796,14 +796,16 @@ static void msc_send_reset(struct bsc_msc_connection *msc_con) static int ipaccess_msc_read_cb(struct osmo_fd *bfd) { struct bsc_msc_connection *msc_con; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; msc_con = (struct bsc_msc_connection *) bfd->data; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_FATAL, "The connection the MSC(%s) was lost, exiting\n", @@ -912,6 +914,13 @@ void bsc_close_connection(struct bsc_connection *connection) osmo_wqueue_clear(&connection->write_queue); llist_del(&connection->list_entry); + if (connection->pending_msg) { + LOGP(DNAT, LOGL_ERROR, "Dropping partial message on connection %d.\n", + connection->cfg->nr); + msgb_free(connection->pending_msg); + connection->pending_msg = NULL; + } + talloc_free(connection); } @@ -1206,13 +1215,15 @@ exit3: static int ipaccess_bsc_read_cb(struct osmo_fd *bfd) { struct bsc_connection *bsc = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct ipaccess_head_ext *hh_ext; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &bsc->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_ERROR, "The connection to the BSC Nr: %d was lost. Cleaning it\n", diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index 8da8181..5f073bf 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -66,6 +66,8 @@ static void bsc_nat_ussd_destroy(struct bsc_nat_ussd_con *con) osmo_fd_unregister(&con->queue.bfd); osmo_timer_del(&con->auth_timeout); osmo_wqueue_clear(&con->queue); + + msgb_free(con->pending_msg); talloc_free(con); } @@ -117,12 +119,14 @@ static int forward_sccp(struct bsc_nat *nat, struct msgb *msg) static int ussd_read_cb(struct osmo_fd *bfd) { struct bsc_nat_ussd_con *conn = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &conn->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n"); bsc_nat_ussd_destroy(conn); return -1; -- 1.7.9.5 From holger at freyther.de Mon Mar 31 13:20:04 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 31 Mar 2014 15:20:04 +0200 Subject: [PATCH] ipa: Use enhanced ipa_msg_recv_buffered() to cope with partioned IPA messages In-Reply-To: <1396266131-31083-1-git-send-email-jerlbeck@sysmocom.de> References: <1395339996-5962-1-git-send-email-jerlbeck@sysmocom.de> <1396266131-31083-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140331132004.GO7456@xiaoyu.lan> On Mon, Mar 31, 2014 at 01:42:11PM +0200, Jacob Erlbeck wrote: Dear Jacob, I think there is a typo in the subject. Can you confirm? > It has been successfully tested by jerlbeck with osmo-nitb and > osmo-bsc. My usual question is: What has been tested? You ran the two processes and did LUs and placed calls? I think it is good to capture this information in the commit message. The patch appears fine! Great to finally have these changes. holger From holger at freyther.de Mon Mar 24 10:30:30 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 24 Mar 2014 11:30:30 +0100 Subject: [PATCH 2/2] ipa: Change ipa_msg_recv() to support partial receive In-Reply-To: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140324103030.GH25795@xiaoyu.lan> On Thu, Mar 20, 2014 at 07:14:34PM +0100, Jacob Erlbeck wrote: > In addition iin case of errors the return value is now always -EXXX Just one 'i', right? > @@ -109,6 +109,8 @@ struct e1inp_ts { > struct osmo_fd fd; > } rs232; > } driver; > + > + struct msgb *pending_msg; > }; > @@ -27,6 +27,7 @@ struct ipa_server_conn { > int (*closed_cb)(struct ipa_server_conn *peer); > int (*cb)(struct ipa_server_conn *peer, struct msgb *msg); > void *data; > + struct msgb *pending_msg; > }; > @@ -53,6 +54,7 @@ struct ipa_client_conn { > int (*read_cb)(struct ipa_client_conn *link, struct msgb *msg); > int (*write_cb)(struct ipa_client_conn *link); > void *data; > + struct msgb *pending_msg; > }; I think you miss a TODO-RELEASE entry? > @@ -415,13 +420,15 @@ static int handle_ts1_read(struct osmo_fd *bfd) > + if (ret == -EAGAIN) > + return; The compiler warns about this return without a value. What is the correct response? The rest is looking fine. From jerlbeck at sysmocom.de Mon Mar 31 08:53:32 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 31 Mar 2014 10:53:32 +0200 Subject: [PATCH] ipa: Change ipa_msg_recv() to support partial receive In-Reply-To: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1396256012-11236-1-git-send-email-jerlbeck@sysmocom.de> Currently ipa_msg_recv() fails, when messages are received partially. This patch provides a new function ipa_msg_recv_buffered() that uses an additional ** to a message buffer to store partial data. When this happens, -EAGAIN is returned. If NULL is used, the function behaves similar to ipa_msg_recv() and fails on partial read. In addition in case of errors the return value is now always -EXXX and the contents of errno is undefined. Note that this feature needs support by the calling code insofar that *tmp_msg must be set to NULL initially and it must be freed and set to NULL manually when the socket is closed. Note also that ipa_msg_recv() is then a wrapper around ipa_msg_recv_buffered() which mimics the old error behaviour by setting errno explicitely to -rc and returning -1 when an error has happened. Ticket: OW#728 Sponsored-by: On-Waves ehf --- TODO-RELEASE | 1 + include/osmocom/abis/e1_input.h | 2 + include/osmocom/abis/ipa.h | 3 + src/input/ipa.c | 151 ++++++++++++++++++++++++++++++--------- src/input/ipaccess.c | 13 +++- tests/ipa_recv/ipa_recv_test.c | 55 +++++++++----- tests/ipa_recv/ipa_recv_test.ok | 27 ++++++- 7 files changed, 198 insertions(+), 54 deletions(-) diff --git a/TODO-RELEASE b/TODO-RELEASE index 43b1e8e..71931db 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -1 +1,2 @@ #library what description / commit summary line +libosmoabis abi-change ipa: Change ipa_msg_recv() to support partial receive diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 9b77893..cf8677b 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -109,6 +109,8 @@ struct e1inp_ts { struct osmo_fd fd; } rs232; } driver; + + struct msgb *pending_msg; }; struct gsm_e1_subslot { diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h index d577d74..982b694 100644 --- a/include/osmocom/abis/ipa.h +++ b/include/osmocom/abis/ipa.h @@ -27,6 +27,7 @@ struct ipa_server_conn { int (*closed_cb)(struct ipa_server_conn *peer); int (*cb)(struct ipa_server_conn *peer, struct msgb *msg); void *data; + struct msgb *pending_msg; }; struct ipa_server_conn *ipa_server_conn_create(void *ctx, struct ipa_server_link *link, int fd, int (*cb)(struct ipa_server_conn *peer, struct msgb *msg), int (*closed_cb)(struct ipa_server_conn *peer), void *data); @@ -53,6 +54,7 @@ struct ipa_client_conn { int (*read_cb)(struct ipa_client_conn *link, struct msgb *msg); int (*write_cb)(struct ipa_client_conn *link); void *data; + struct msgb *pending_msg; }; struct ipa_client_conn *ipa_client_conn_create(void *ctx, struct e1inp_ts *ts, int priv_nr, const char *addr, uint16_t port, void (*updown)(struct ipa_client_conn *link, int), int (*read_cb)(struct ipa_client_conn *link, struct msgb *msgb), int (*write_cb)(struct ipa_client_conn *link), void *data); @@ -64,6 +66,7 @@ void ipa_client_conn_close(struct ipa_client_conn *link); void ipa_client_conn_send(struct ipa_client_conn *link, struct msgb *msg); int ipa_msg_recv(int fd, struct msgb **rmsg); +int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg); int ipaccess_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd); diff --git a/src/input/ipa.c b/src/input/ipa.c index b5abd36..71e1227 100644 --- a/src/input/ipa.c +++ b/src/input/ipa.c @@ -49,50 +49,130 @@ void ipa_msg_push_header(struct msgb *msg, uint8_t proto) int ipa_msg_recv(int fd, struct msgb **rmsg) { - struct msgb *msg; + int rc = ipa_msg_recv_buffered(fd, rmsg, NULL); + if (rc < 0) { + errno = -rc; + rc = -1; + } + return rc; +} + +int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg) +{ + struct msgb *msg = tmp_msg ? *tmp_msg : NULL; struct ipaccess_head *hh; int len, ret; + int needed; - msg = ipa_msg_alloc(0); if (msg == NULL) - return -ENOMEM; + msg = ipa_msg_alloc(0); - /* first read our 3-byte header */ - hh = (struct ipaccess_head *) msg->data; - ret = recv(fd, msg->data, sizeof(*hh), 0); - if (ret <= 0) { - msgb_free(msg); - return ret; - } else if (ret != sizeof(*hh)) { - LOGP(DLINP, LOGL_ERROR, "too small message received\n"); - msgb_free(msg); - return -EIO; + if (msg == NULL) { + ret = -ENOMEM; + goto discard_msg; } - msgb_put(msg, ret); + + if (msg->l2h == NULL) { + /* first read our 3-byte header */ + needed = sizeof(*hh) - msg->len; + ret = recv(fd, msg->tail, needed, 0); + if (ret == 0) + goto discard_msg; + + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + ret = 0; + else { + ret = -errno; + goto discard_msg; + } + } + + msgb_put(msg, ret); + + if (ret < needed) { + if (msg->len == 0) { + ret = -EAGAIN; + goto discard_msg; + } + + LOGP(DLINP, LOGL_INFO, + "Received part of IPA message header (%d/%d)\n", + msg->len, sizeof(*hh)); + if (!tmp_msg) { + ret = -EIO; + goto discard_msg; + } + *tmp_msg = msg; + return -EAGAIN; + } + + msg->l2h = msg->tail; + } + + hh = (struct ipaccess_head *) msg->data; /* then read the length as specified in header */ - msg->l2h = msg->data + sizeof(*hh); len = ntohs(hh->len); if (len < 0 || IPA_ALLOC_SIZE < len + sizeof(*hh)) { LOGP(DLINP, LOGL_ERROR, "bad message length of %d bytes, " - "received %d bytes\n", len, ret); - msgb_free(msg); - return -EIO; + "received %d bytes\n", len, msg->len); + ret = -EIO; + goto discard_msg; } - ret = recv(fd, msg->l2h, len, 0); - if (ret <= 0) { - msgb_free(msg); - return ret; - } else if (ret < len) { - LOGP(DLINP, LOGL_ERROR, "truncated message received\n"); - msgb_free(msg); - return -EIO; + needed = len - msgb_l2len(msg); + + if (needed > 0) { + ret = recv(fd, msg->tail, needed, 0); + + if (ret == 0) + goto discard_msg; + + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + ret = 0; + else { + ret = -errno; + goto discard_msg; + } + } + + msgb_put(msg, ret); + + if (ret < needed) { + LOGP(DLINP, LOGL_INFO, + "Received part of IPA message L2 data (%d/%d)\n", + msgb_l2len(msg), len); + if (!tmp_msg) { + ret = -EIO; + goto discard_msg; + } + *tmp_msg = msg; + return -EAGAIN; + } } - msgb_put(msg, ret); + + ret = msgb_l2len(msg); + + if (ret == 0) { + LOGP(DLINP, LOGL_INFO, + "Discarding IPA message without payload\n"); + ret = -EAGAIN; + goto discard_msg; + } + + if (tmp_msg) + *tmp_msg = NULL; *rmsg = msg; return ret; + +discard_msg: + if (tmp_msg) + *tmp_msg = NULL; + msgb_free(msg); + return ret; } void ipa_client_conn_close(struct ipa_client_conn *link) @@ -103,6 +183,8 @@ void ipa_client_conn_close(struct ipa_client_conn *link) close(link->ofd->fd); link->ofd->fd = -1; } + msgb_free(link->pending_msg); + link->pending_msg = NULL; } static void ipa_client_read(struct ipa_client_conn *link) @@ -113,11 +195,12 @@ static void ipa_client_read(struct ipa_client_conn *link) LOGP(DLINP, LOGL_DEBUG, "message received\n"); - ret = ipa_msg_recv(ofd->fd, &msg); + ret = ipa_msg_recv_buffered(ofd->fd, &msg, &link->pending_msg); if (ret < 0) { - if (errno == EPIPE || errno == ECONNRESET) { + if (ret == -EAGAIN) + return; + if (ret == -EPIPE || ret == -ECONNRESET) LOGP(DLINP, LOGL_ERROR, "lost connection with server\n"); - } ipa_client_conn_close(link); if (link->updown_cb) link->updown_cb(link, 0); @@ -382,11 +465,12 @@ static void ipa_server_conn_read(struct ipa_server_conn *conn) LOGP(DLINP, LOGL_DEBUG, "message received\n"); - ret = ipa_msg_recv(ofd->fd, &msg); + ret = ipa_msg_recv_buffered(ofd->fd, &msg, &conn->pending_msg); if (ret < 0) { - if (errno == EPIPE || errno == ECONNRESET) { + if (ret == -EAGAIN) + return; + if (ret == -EPIPE || ret == -ECONNRESET) LOGP(DLINP, LOGL_ERROR, "lost connection with server\n"); - } ipa_server_conn_destroy(conn); return; } else if (ret == 0) { @@ -471,6 +555,7 @@ ipa_server_conn_create(void *ctx, struct ipa_server_link *link, int fd, void ipa_server_conn_destroy(struct ipa_server_conn *conn) { close(conn->ofd.fd); + msgb_free(conn->pending_msg); osmo_fd_unregister(&conn->ofd); if (conn->closed_cb) conn->closed_cb(conn); diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 225d70c..7ac5ad1 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -258,6 +258,8 @@ int ipaccess_rcvmsg_bts_base(struct msgb *msg, static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line) { int ret = 1; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; /* Error case: we did not see any ID_RESP yet for this socket. */ if (bfd->fd != -1) { @@ -269,6 +271,9 @@ static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line) ret = -ENOENT; } + msgb_free(e1i_ts->pending_msg); + e1i_ts->pending_msg = NULL; + /* e1inp_sign_link_destroy releases the socket descriptors for us. */ line->ops->sign_link_down(line); @@ -415,13 +420,15 @@ static int handle_ts1_read(struct osmo_fd *bfd) struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; struct e1inp_sign_link *link; struct ipaccess_head *hh; - struct msgb *msg; + struct msgb *msg = NULL; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &e1i_ts->pending_msg); if (ret < 0) { + if (ret == -EAGAIN) + return 0; LOGP(DLINP, LOGL_NOTICE, "Sign link problems, " - "closing socket. Reason: %s\n", strerror(errno)); + "closing socket. Reason: %s\n", strerror(-ret)); goto err; } else if (ret == 0) { LOGP(DLINP, LOGL_NOTICE, "Sign link vanished, dead socket\n"); diff --git a/tests/ipa_recv/ipa_recv_test.c b/tests/ipa_recv/ipa_recv_test.c index 7b26259..8cdc7e2 100644 --- a/tests/ipa_recv/ipa_recv_test.c +++ b/tests/ipa_recv/ipa_recv_test.c @@ -86,7 +86,7 @@ static void append_ipa_message(struct msgb *msg, int proto, const char *text) strcpy((char *)l2, text); } -static int receive_messages(int fd) +static int receive_messages(int fd, struct msgb **pending_msg) { struct msgb *msg; char dummy; @@ -97,13 +97,22 @@ static int receive_messages(int fd) break; } msg = NULL; - rc = ipa_msg_recv(fd, &msg); - if (rc == -1) - rc = -errno; + rc = ipa_msg_recv_buffered(fd, &msg, pending_msg); + fprintf(stderr, - "ipa_msg_recv: %d, msg %s NULL\n", - rc, msg ? "!=" : "=="); - if (rc == -EAGAIN) + "ipa_msg_recv_buffered: %d, msg %s NULL, " + "pending_msg %s NULL\n", + rc, msg ? "!=" : "==", + !pending_msg ? "??" : *pending_msg ? "!=" : "=="); + if (pending_msg && !!msg == !!*pending_msg) + printf( "got msg %s NULL, pending_msg %s NULL, " + "returned: %s\n", + msg ? "!=" : "==", + *pending_msg ? "!=" : "==", + rc == 0 ? "EOF" : + rc > 0 ? "OK" : + strerror(-rc)); + else if (!pending_msg && rc == -EAGAIN) printf( "got msg %s NULL, " "returned: %s\n", msg ? "!=" : "==", @@ -115,7 +124,8 @@ static int receive_messages(int fd) if (rc == -EAGAIN) break; if (rc < 0) { - printf("ipa_msg_recv failed with: %s\n", strerror(-rc)); + printf("ipa_msg_recv_buffered failed with: %s\n", + strerror(-rc)); return rc; } printf("got IPA message, size=%d, proto=%d, text=\"%s\"\n", @@ -142,13 +152,15 @@ static int slurp_data(int fd) { return count; }; -static void test_complete_recv(void) +static void test_complete_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with complete messages.\n"); + printf("Testing IPA recv with complete messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -166,7 +178,11 @@ static void test_complete_recv(void) } for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) { - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); + if (pending_msg) + printf("Unexpected partial message: size=%d\n", + pending_msg->len); if (rc == 0) break; @@ -181,16 +197,19 @@ static void test_complete_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } -static void test_partial_recv(void) +static void test_partial_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with partitioned messages.\n"); + printf("Testing IPA recv with partitioned messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -211,7 +230,8 @@ static void test_partial_recv(void) if (msg_out->len == 0) shutdown(sv[1], SHUT_WR); - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); if (rc == 0) break; @@ -226,6 +246,7 @@ static void test_partial_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } static struct log_info info = {}; @@ -239,8 +260,10 @@ int main(int argc, char **argv) printf("Testing the IPA layer.\n"); /* run the tests */ - test_complete_recv(); - test_partial_recv(); + test_complete_recv(1); + test_partial_recv(1); + test_complete_recv(0); + test_partial_recv(0); printf("No crashes.\n"); return 0; diff --git a/tests/ipa_recv/ipa_recv_test.ok b/tests/ipa_recv/ipa_recv_test.ok index 4144d47..bdbfb7d 100644 --- a/tests/ipa_recv/ipa_recv_test.ok +++ b/tests/ipa_recv/ipa_recv_test.ok @@ -5,8 +5,31 @@ got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMN got IPA message, size=16, proto=200, text="Hello again IPA" got IPA message, size=1, proto=200, text="" got IPA message, size=14, proto=200, text="Next is empty" -done: unread 14, unsent 0 +got msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 Testing IPA recv with partitioned messages. -ipa_msg_recv failed with: Input/output error +ipa_msg_recv_buffered failed with: Input/output error done: unread 0, unsent 154 +Testing IPA recv with complete messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 +Testing IPA recv with partitioned messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 No crashes. -- 1.7.9.5 From holger at freyther.de Mon Mar 31 13:07:28 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 31 Mar 2014 15:07:28 +0200 Subject: [PATCH] ipa: Change ipa_msg_recv() to support partial receive In-Reply-To: <1396256012-11236-1-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-2-git-send-email-jerlbeck@sysmocom.de> <1396256012-11236-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140331130728.GN7456@xiaoyu.lan> On Mon, Mar 31, 2014 at 10:53:32AM +0200, Jacob Erlbeck wrote: Dear Jacob, > + /* first read our 3-byte header */ > + needed = sizeof(*hh) - msg->len; > + ret = recv(fd, msg->tail, needed, 0); > + if (ret == 0) > + goto discard_msg; > + > + if (ret < 0) { > + if (errno == EAGAIN || errno == EINTR) > + ret = 0; > + else { > + ret = -errno; > + goto discard_msg; > + } > + } > + > + msgb_put(msg, ret); > + > + if (ret < needed) { > + if (msg->len == 0) { > + ret = -EAGAIN; > + goto discard_msg; > + } > + > + LOGP(DLINP, LOGL_INFO, > + "Received part of IPA message header (%d/%d)\n", > + msg->len, sizeof(*hh)); ^ tab vs. spaces? > + if (!tmp_msg) { > + ret = -EIO; > + goto discard_msg; > + } > + *tmp_msg = msg; > + return -EAGAIN; > + } > + > + msg->l2h = msg->tail; > + } > + if (needed > 0) { > + ret = recv(fd, msg->tail, needed, 0); > + > + if (ret == 0) > + goto discard_msg; > + > + if (ret < 0) { > + if (errno == EAGAIN || errno == EINTR) > + ret = 0; > + else { > + ret = -errno; > + goto discard_msg; > + } > + } > + > + msgb_put(msg, ret); > + > + if (ret < needed) { > + LOGP(DLINP, LOGL_INFO, > + "Received part of IPA message L2 data (%d/%d)\n", > + msgb_l2len(msg), len); > + if (!tmp_msg) { > + ret = -EIO; > + goto discard_msg; > + } > + *tmp_msg = msg; > + return -EAGAIN; > + } > } Do you think readability would be improved if these two paths could be united? I will push and make releases today for this new feature. From holger at freyther.de Mon Mar 24 10:19:01 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 24 Mar 2014 11:19:01 +0100 Subject: [PATCH 1/2] ipa/test: Add test program for IPA message reception In-Reply-To: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> References: <1395339274-24803-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140324101901.GG25795@xiaoyu.lan> On Thu, Mar 20, 2014 at 07:14:33PM +0100, Jacob Erlbeck wrote: > +/* (C) 2014 by On-Waves I added sysmocom too. > +#if 0 .. > +#endif and removed these From holger at freyther.de Thu Mar 20 20:43:56 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Mar 2014 21:43:56 +0100 Subject: DRAFT for a 30C3 report. Care to review? Message-ID: <20140320204356.GA2398@xiaoyu.lan> hi, Daniel and me started a small report for the 30C3 network but we are kind of stalled. Anyone feels like doing some review and providing feedback? holger -------------- next part -------------- A non-text attachment was scrubbed... Name: report_30c3.pdf Type: application/pdf Size: 764130 bytes Desc: not available URL: From ralph at schmid.xxx Sat Mar 29 18:48:31 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Sat, 29 Mar 2014 19:48:31 +0100 Subject: DRAFT for a 30C3 report. Care to review? In-Reply-To: <20140320204356.GA2398@xiaoyu.lan> References: <20140320204356.GA2398@xiaoyu.lan> Message-ID: <000901cf4b7f$7b476500$71d62f00$@schmid.xxx> Although I have not been there I am reading this with interest. Regarding 4.1, when people start playing with their SIMs and trying manual registering into Vodafone, the forbidden network is deleted from the SIM, so this measure only is effective against accidentally catching the wrong network - or is there another field in the SIM that totally blocks access to certain networks? 4.2, I am OpenBTS user, but I also have sometimes strange behavior when LU is missed for some reason, or when the BTS is restarted. 6., early call assignment seems to make problems with some phones, at least with OpenBTS and old Sagem phones this feature makes the phones ring for very short time, then the call attempt ends, and a missed call shows up in the display. This year I plan to attend... Ralph. > -----Original Message----- > From: openbsc-bounces at lists.osmocom.org [mailto:openbsc-bounces at lists.osmocom.org] On Behalf Of Holger Hans Peter Freyther > Sent: Thursday, 20 March, 2014 21:44 > To: openbsc at lists.osmocom.org > Subject: DRAFT for a 30C3 report. Care to review? > > hi, > > Daniel and me started a small report for the 30C3 network but we are kind of stalled. Anyone feels like doing some review and providing > feedback? > > > holger From tele at rhizomatica.org Mon Mar 31 17:08:08 2014 From: tele at rhizomatica.org (tele) Date: Mon, 31 Mar 2014 12:08:08 -0500 Subject: DRAFT for a 30C3 report. Care to review? In-Reply-To: <20140320204356.GA2398@xiaoyu.lan> References: <20140320204356.GA2398@xiaoyu.lan> Message-ID: <20140331120808.5ca86c61@2cb> Hi Holger, Would be interesting to provide traffic volume and number of subscribers that used the network those days. :tele On Thu, 20 Mar 2014 21:43:56 +0100 Holger Hans Peter Freyther wrote: > hi, > > Daniel and me started a small report for the 30C3 network but we > are kind of stalled. Anyone feels like doing some review and > providing feedback? > > > holger From openbsc-bounces at lists.osmocom.org Fri Mar 21 07:00:25 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Fri, 21 Mar 2014 08:00:25 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From pablo at gnumonks.org Fri Mar 21 11:08:49 2014 From: pablo at gnumonks.org (pablo at gnumonks.org) Date: Fri, 21 Mar 2014 12:08:49 +0100 Subject: [PATCH openggsn v2] gtp: fix endianness in teid field of GTPv0 header Message-ID: <1395400129-21471-1-git-send-email-pablo@gnumonks.org> From: Pablo Neira Ayuso This field needs to be in network byte order as well. This problem may manifest if you use ggsn and sgsn with different endianness. It also show up when using the gtp kernel mode since the downlink packets are using network byte order in the 64-bits teid field, which osmo-sgsn / libgtp doesn't expect. --- v2: Add function to encapsulate the code to access and to build the teid as Holger suggested. Tested with and without gtp kernel support. If no objections, I'll push this to master. gtp/gtp.c | 34 +++++++++++++--------------------- gtp/pdp.c | 6 ++++++ gtp/pdp.h | 2 ++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/gtp/gtp.c b/gtp/gtp.c index 3cc0c0b..6185634 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -250,7 +250,7 @@ static uint64_t get_tid(void *pack) union gtp_packet *packet = (union gtp_packet *)pack; if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */ - return packet->gtp0.h.tid; + return be64toh(packet->gtp0.h.tid); } return 0; } @@ -425,10 +425,10 @@ int gtp_req(struct gsn_t *gsn, int version, struct pdp_t *pdp, addr.sin_port = htons(GTP0_PORT); packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); packet->gtp0.h.seq = hton16(gsn->seq_next); - if (pdp) + if (pdp) { packet->gtp0.h.tid = - (pdp->imsi & 0x0fffffffffffffffull) + - ((uint64_t) pdp->nsapi << 60); + htobe64(pdp_gettid(pdp->imsi, pdp->nsapi)); + } if (pdp && ((packet->gtp0.h.type == GTP_GPDU) || (packet->gtp0.h.type == GTP_ERROR))) packet->gtp0.h.flow = hton16(pdp->flru); @@ -581,7 +581,7 @@ int gtp_resp(int version, struct gsn_t *gsn, struct pdp_t *pdp, if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */ packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE); packet->gtp0.h.seq = hton16(seq); - packet->gtp0.h.tid = tid; + packet->gtp0.h.tid = htobe64(tid); if (pdp && ((packet->gtp0.h.type == GTP_GPDU) || (packet->gtp0.h.type == GTP_ERROR))) packet->gtp0.h.flow = hton16(pdp->flru); @@ -1329,12 +1329,9 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version, memset(pdp, 0, sizeof(struct pdp_t)); if (version == 0) { - pdp->imsi = - ((union gtp_packet *)pack)->gtp0. - h.tid & 0x0fffffffffffffffull; - pdp->nsapi = - (((union gtp_packet *)pack)->gtp0. - h.tid & 0xf000000000000000ull) >> 60; + uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid); + + pdp_set_imsi_nsapi(pdp, tid); } pdp->seq = seq; @@ -2051,12 +2048,9 @@ int gtp_update_pdp_ind(struct gsn_t *gsn, int version, /* For GTP1 we must use imsi and nsapi if imsi is present. Otherwise */ /* we have to use the tunnel endpoint identifier */ if (version == 0) { - imsi = - ((union gtp_packet *)pack)->gtp0. - h.tid & 0x0fffffffffffffffull; - nsapi = - (((union gtp_packet *)pack)->gtp0. - h.tid & 0xf000000000000000ull) >> 60; + uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid); + + pdp_set_imsi_nsapi(pdp, tid); /* Find the context in question */ if (pdp_getimsi(&pdp, imsi, nsapi)) { @@ -2645,7 +2639,7 @@ int gtp_error_ind_conf(struct gsn_t *gsn, int version, struct pdp_t *pdp; /* Find the context in question */ - if (pdp_tidget(&pdp, ((union gtp_packet *)pack)->gtp0.h.tid)) { + if (pdp_tidget(&pdp, be64toh(((union gtp_packet *)pack)->gtp0.h.tid))) { gsn->err_unknownpdp++; gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len, "Unknown PDP context"); @@ -3196,9 +3190,7 @@ int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len) packet.gtp0.h.length = hton16(len); packet.gtp0.h.seq = hton16(pdp->gtpsntx++); packet.gtp0.h.flow = hton16(pdp->flru); - packet.gtp0.h.tid = - (pdp->imsi & 0x0fffffffffffffffull) + - ((uint64_t) pdp->nsapi << 60); + packet.gtp0.h.tid = htobe64(pdp_gettid(pdp->imsi, pdp->nsapi)); if (len > sizeof(union gtp_packet) - sizeof(struct gtp0_header)) { gsn->err_memcpy++; diff --git a/gtp/pdp.c b/gtp/pdp.c index dfb91ea..dc21bf8 100644 --- a/gtp/pdp.c +++ b/gtp/pdp.c @@ -370,6 +370,12 @@ uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi) return (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60); } +void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid) +{ + pdp->imsi = teid & 0x0fffffffffffffffull; + pdp->nsapi = (teid & 0xf000000000000000ull) >> 60; +} + int ulcpy(void *dst, void *src, size_t size) { if (((struct ul255_t *)src)->l <= size) { diff --git a/gtp/pdp.h b/gtp/pdp.h index b069a6f..6e30467 100644 --- a/gtp/pdp.h +++ b/gtp/pdp.h @@ -242,6 +242,8 @@ int pdp_tidset(struct pdp_t *pdp, uint64_t tid); int pdp_tiddel(struct pdp_t *pdp); int pdp_tidget(struct pdp_t **pdp, uint64_t tid); +void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid); + /* int pdp_iphash(void* ipif, struct ul66_t *eua); int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua); -- 1.7.10.4 From holger at freyther.de Sun Mar 23 19:52:37 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 23 Mar 2014 20:52:37 +0100 Subject: [PATCH openggsn v2] gtp: fix endianness in teid field of GTPv0 header In-Reply-To: <1395400129-21471-1-git-send-email-pablo@gnumonks.org> References: <1395400129-21471-1-git-send-email-pablo@gnumonks.org> Message-ID: <20140323195237.GL15530@xiaoyu.lan> On Fri, Mar 21, 2014 at 12:08:49PM +0100, pablo at gnumonks.org wrote: > From: Pablo Neira Ayuso > > This field needs to be in network byte order as well. This problem > may manifest if you use ggsn and sgsn with different endianness. > It also show up when using the gtp kernel mode since the downlink > packets are using network byte order in the 64-bits teid field, > which osmo-sgsn / libgtp doesn't expect. > --- > v2: Add function to encapsulate the code to access and to build > the teid as Holger suggested. looks good. From valtulina.luca at gmail.com Fri Mar 21 15:09:03 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Fri, 21 Mar 2014 16:09:03 +0100 Subject: Possibility to use INET socket for external MNCC Message-ID: Hi list, wouldn't be useful to have the possibility to choose (at least) between UNIX and INET socket to be used for connecting to an external MNCC? If this will be the case where should the choice be made? I was thinking to add an extra option to bsc_hack but the choice can also be hard-coded (prior to compilation). cheers luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Fri Mar 21 16:24:12 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 21 Mar 2014 20:24:12 +0400 Subject: Possibility to use INET socket for external MNCC In-Reply-To: References: Message-ID: Hi Luca, The first question is why do you need to do that? If this is to be implemented, this looks like a VTY (i.e. configuration) option to me. On Fri, Mar 21, 2014 at 7:09 PM, Luca Valtulina wrote: > Hi list, > > wouldn't be useful to have the possibility to choose (at least) between UNIX > and INET socket to be used for connecting to an external MNCC? > > If this will be the case where should the choice be made? I was thinking to > add an extra option to bsc_hack but the choice can also be hard-coded (prior > to compilation). > > cheers > luca -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. / ??? ??????? https://fairwaves.co From valtulina.luca at gmail.com Mon Mar 24 10:18:12 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Mon, 24 Mar 2014 11:18:12 +0100 Subject: Possibility to use INET socket for external MNCC In-Reply-To: References: Message-ID: > Hi Luca, > Hi Alexander, > The first question is why do you need to do that? > Well for instance, specific network design can lead to have an external MNCC in a different location/machine than OpenBSC. I know that LCR already offer the possibility to setup a UDP socket with a SIP endpoint but what if LCR is not to be used? I think that having the option to setup a INET socket also for OpenBSC can offer more dynamic network deployments. luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From laforge at gnumonks.org Mon Mar 31 14:54:13 2014 From: laforge at gnumonks.org (Harald Welte) Date: Mon, 31 Mar 2014 16:54:13 +0200 Subject: Possibility to use INET socket for external MNCC In-Reply-To: References: Message-ID: <20140331145413.GB13291@nataraja> On Fri, Mar 21, 2014 at 04:09:03PM +0100, Luca Valtulina wrote: > wouldn't be useful to have the possibility to choose (at least) between > UNIX and INET socket to be used for connecting to an external MNCC? There are several problems with this: 1) the MNCC interface carries both voice and signalling. For signalling you would like something that resembles TCP/SCTP/DCCP, but for the voice you would only like UDP semantics. Choosing either a reliable protocol for voice frames or an unrealiable protocol for signalling is calling for lots of trouble and will not happen. So it would have to be multiple sockets. 2) I don't think the current protocol is endian/alignment safe. By runnign it over a unix domain socket we basically enforce that both programs on the MNCC side will run on the same architectuer and not cause any problems. If you run it over a network, making that assumption is false. So yes, it could be possible to run MNCC over IP/INET sockets, but it would require considerable effort of addressing the issues described above. Will you be working on implementing this? 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 valtulina.luca at gmail.com Mon Mar 31 15:34:57 2014 From: valtulina.luca at gmail.com (Luca Valtulina) Date: Mon, 31 Mar 2014 17:34:57 +0200 Subject: Possibility to use INET socket for external MNCC In-Reply-To: <20140331145413.GB13291@nataraja> References: <20140331145413.GB13291@nataraja> Message-ID: > 1) the MNCC interface carries both voice and signalling. For signalling > you would like something that resembles TCP/SCTP/DCCP, but for the > voice you would only like UDP semantics. Choosing either a reliable > protocol for voice frames or an unrealiable protocol for signalling > is calling for lots of trouble and will not happen. So it would have > to be multiple sockets. > Currently I am establishing RTP sockets for voice (from jolly/testing branch) while a TCP/IP socket is used for signaling. So yes MNCC socket is used only for signaling (I though also about the possibility of using it as a "backup" socket in case RTP fails but then the reliable vs unreliable issue pops up) > 2) I don't think the current protocol is endian/alignment safe. By > runnign it over a unix domain socket we basically enforce that both > programs on the MNCC side will run on the same architectuer and not > cause any problems. If you run it over a network, making that > assumption is false. > The endianness can be carried in the payload of any packet to make it safer or it can be exchanged upon socket setup for instance in the MNCC_SOCKET_HELLO message. Currently I am carrying the size of the sent signaling message in order to distinguish between gsm_mncc and gsm_mncc_rtp (for now). I did it more as a try than everything but I thought it was a waste to send 840 bytes of data when gsm_mncc_rtp messages are only 24 bytes long! > Will you be working on implementing this? > I might need a certain amount of guidance due to my lack of experience. Luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From Max.Suraev at fairwaves.ru Mon Mar 31 15:38:19 2014 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Mon, 31 Mar 2014 17:38:19 +0200 Subject: Possibility to use INET socket for external MNCC In-Reply-To: References: Message-ID: <53398BEB.7020701@fairwaves.ru> You can try playing with socat tool ( http://www.dest-unreach.org/socat/ ) to forward unix socket over ip transparently to the application using it. I'm not sure how practical it would be - I mean how big additional latencies introduced and potential throughput and such. 21.03.2014 16:09, Luca Valtulina ?????: > Hi list, > > wouldn't be useful to have the possibility to choose (at least) between UNIX and INET > socket to be used for connecting to an external MNCC? > > If this will be the case where should the choice be made? I was thinking to add an > extra option to bsc_hack but the choice can also be hard-coded (prior to compilation). > -- best regards, Max, http://fairwaves.ru From openbsc-bounces at lists.osmocom.org Sat Mar 22 07:00:11 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Sat, 22 Mar 2014 08:00:11 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From openbsc-bounces at lists.osmocom.org Sun Mar 23 07:00:09 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Sun, 23 Mar 2014 08:00:09 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From openbsc-bounces at lists.osmocom.org Mon Mar 24 07:00:14 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Mon, 24 Mar 2014 08:00:14 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From openbsc-bounces at lists.osmocom.org Tue Mar 25 07:00:11 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Tue, 25 Mar 2014 08:00:11 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From openbsc-bounces at lists.osmocom.org Wed Mar 26 07:00:12 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Wed, 26 Mar 2014 08:00:12 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From anayuso at sysmocom.de Wed Mar 26 16:10:36 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Wed, 26 Mar 2014 17:10:36 +0100 Subject: [osmo-bts PATCH] src: Add OML support for sending failure message from manager Message-ID: <1395850236-6570-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso With this patch, the manager monitors the sensors and send OML Failure message from the Manager to the BTS and the BTS to BSC, for having a report system of the sensors. Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/main.c | 45 ++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 35 +++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 120 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_misc.h | 32 +++++++++ 4 files changed, 231 insertions(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 74ee47f..a86d41e 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -45,8 +46,10 @@ #include #include #include +#include #define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock" +#define SOCKET_PATH "/tmp/echo_temp" #include "utils.h" #include "eeprom.h" @@ -258,6 +261,7 @@ static void signal_handler(int signal) case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); bts_shutdown(bts, "SIGINT"); + unlink(SOCKET_PATH); break; case SIGABRT: case SIGUSR1: @@ -288,6 +292,38 @@ static int write_pid_file(char *procname) return 0; } +static int read_unix_sock(struct osmo_fd *fd, unsigned int what) +{ + int sfd = fd->fd, cl, rc = 1; + struct msgb *msg; + struct gsm_abis_mo *mo; + + cl = accept(sfd, NULL, NULL); + if (cl < 0) + return -1; + + msg = oml_msgb_alloc(); + if (msg == NULL) + return -1; + + while (rc > 0) { + rc = recv(cl, msg->tail, msg->data_len, 0); + if (rc < 0) + return -1; + else if (rc == 0) + break; + + msgb_put(msg, rc); + } + close(cl); + mo = &bts->mo; + msg->trx = mo->bts->c0; + msg->l2h = msg->data; + msg->l3h = msg->data + sizeof(struct abis_om_fom_hdr); + + return abis_oml_sendmsg(msg); +} + int main(int argc, char **argv) { struct stat st; @@ -295,6 +331,7 @@ int main(int argc, char **argv) struct gsm_bts_role_bts *btsb; struct e1inp_line *line; void *tall_msgb_ctx; + struct osmo_fd fd; int rc; tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); @@ -370,6 +407,14 @@ int main(int argc, char **argv) fprintf(stderr, "unable to connect to BSC\n"); exit(1); } + fd.cb = read_unix_sock; + + rc = osmo_sock_unix_init_ofd(&fd, SOCK_STREAM, 0, SOCKET_PATH, + OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); + if (rc < 0) { + perror("Error creating socket domain creation"); + exit(3); + } if (daemonize) { rc = osmo_daemonize(); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 6c64d0f..d547dbe 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ static int no_eeprom_write = 0; static int daemonize = 0; void *tall_mgr_ctx; +struct sbts2050_config_info confinfo; /* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */ #define TEMP_TIMER_SECS (6 * 3600) @@ -64,6 +66,39 @@ static void check_uctemp_timer_cb(void *data) sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); + confinfo.temp_pa_cur = temp_pa; + confinfo.temp_board_cur = temp_board; + + if (confinfo.temp_min_pa_warn_limit > temp_pa || + confinfo.temp_max_pa_warn_limit < temp_pa) { + sendto_osmobts(ucontrol0, SBTS2050_WARN_ALERT, + SBTS2050_TEMP_PA, &confinfo); + } else if (confinfo.temp_min_pa_sever_limit > temp_pa || + confinfo.temp_max_pa_sever_limit < temp_pa) { + sendto_osmobts(ucontrol0, SBTS2050_SEVER_ALERT, + SBTS2050_TEMP_PA, &confinfo); + sbts2050_uc_power(ucontrol0, + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_MASTER), + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_SLAVE), + confinfo.pa_power_act); + } + + if (confinfo.temp_min_board_warn_limit > temp_board || + confinfo.temp_max_board_warn_limit < temp_board) { + sendto_osmobts(ucontrol0, SBTS2050_WARN_ALERT, + SBTS2050_TEMP_BOARD, &confinfo); + } else if (confinfo.temp_min_board_sever_limit > temp_board || + confinfo.temp_max_board_sever_limit < temp_board) { + sendto_osmobts(ucontrol0, SBTS2050_SEVER_ALERT, + SBTS2050_TEMP_BOARD, &confinfo); + sbts2050_uc_power(ucontrol0, confinfo.master_power_act, + confinfo.slave_power_act, + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_PA)); + } + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); } #endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 9ea26c2..44bffad 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -29,13 +29,17 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include +#include #include "btsconfig.h" #include "sysmobts_misc.h" @@ -49,10 +53,124 @@ #define SERIAL_ALLOC_SIZE 300 #define SIZE_HEADER_RSP 5 #define SIZE_HEADER_CMD 4 - +#define OM_ALLOC_SIZE 1024 +#define OM_HEADROOM_SIZE 128 +#define SOCKET_PATH "/tmp/echo_temp" #ifdef BUILD_SBTS2050 /********************************************************************** + * Function send information to OsmoBts + *********************************************************************/ +static void create_oml_hdr_msg(struct msgb *msg, uint8_t msg_type, + uint8_t obj_class, uint8_t bts_nr, + uint8_t trx_nr, uint8_t ts_nr) +{ + struct abis_om_fom_hdr *foh; + struct abis_om_hdr *omh; + + msg->l3h = msgb_push(msg, sizeof(*foh)); + foh = (struct abis_om_fom_hdr *) msg->l3h; + + foh->msg_type = msg_type; + foh->obj_class = obj_class; + foh->obj_inst.bts_nr = bts_nr; + foh->obj_inst.trx_nr = trx_nr; + foh->obj_inst.ts_nr = ts_nr; + + msg->l2h = msgb_push(msg, sizeof(*omh)); + omh = (struct abis_om_hdr *) msg->l2h; + + omh->mdisc = ABIS_OM_MDISC_FOM; + omh->placement = ABIS_OM_PLACEMENT_ONLY; + omh->sequence = 0; + omh->length = msgb_l3len(msg); +} + +int sendto_osmobts(struct uc *ucontrol, enum sbts2050_alert_lvl alert, + enum sbts2050_temp_sensor sensor, + struct sbts2050_config_info *add_info) +{ + int rc, val, fd; + struct msgb *msg; + const char *buf, *nsensor; + char version[20]; + + msg = msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + goto err; + } + + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) + goto err; + + create_oml_hdr_msg(msg, NM_MT_FAILURE_EVENT_REP, 0, 0, val, 0); + + msgb_tv_put(msg, NM_ATT_EVENT_TYPE, NM_EVT_ENV_FAIL); + + switch (alert) { + case SBTS2050_WARN_ALERT: + msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_WARNING); + break; + case SBTS2050_SEVER_ALERT: + msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_CRITICAL); + break; + default: + goto err; + } + + msgb_tv_put(msg, NM_ATT_PROB_CAUSE, NM_PCAUSE_T_MANUF); + + strcpy(version, PACKAGE_VERSION); + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, 0, 0); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, strlen(version), + (const uint8_t *)version); + + switch (sensor){ + case SBTS2050_TEMP_BOARD: + buf = "Unusual temperature on the Board"; + nsensor = "Board"; + break; + case SBTS2050_TEMP_PA: + buf = "Unusual temperature on the PA"; + nsensor = "PA"; + break; + default: + return -1; + } + strncpy(add_info->name_sensor, nsensor, strlen(nsensor)); + + msgb_tlv_put(msg, NM_ATT_ADD_TEXT, strlen(buf)+1, (const uint8_t *)buf); + + //If we need to send this structure to other machine, we need to pass + //the integer inside the structure to internet format (big endian) + msgb_tlv_put(msg, NM_ATT_ADD_INFO, sizeof(struct sbts2050_config_info ), + (const uint8_t *)add_info); + + fd = osmo_sock_unix_init(SOCK_STREAM, 0, SOCKET_PATH, + OSMO_SOCK_F_CONNECT); + if (fd < 0) { + LOGP(DTEMP, LOGL_ERROR, "Error creating unix socket\n"); + goto err; + } + + rc = write(fd, msg->data, msg->len); + if (rc < 0) { + LOGP(DTEMP, LOGL_ERROR, "Error writting in unix socket\n"); + close(fd); + goto err; + } + + close(fd); + msgb_free(msg); + return 0; +err: + msgb_free(msg); + return -1; +} + +/********************************************************************** * Functions read/write from serial interface *********************************************************************/ static int hand_serial_read(int fd, struct msgb *msg, int numbytes) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 01878f2..a2e90cf 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -32,6 +32,34 @@ struct ucinfo { int pa; }; +enum sbts2050_alert_lvl { + SBTS2050_WARN_ALERT, + SBTS2050_SEVER_ALERT +}; + +enum sbts2050_temp_sensor { + SBTS2050_TEMP_BOARD, + SBTS2050_TEMP_PA +}; + +struct sbts2050_config_info { + char name_sensor[8]; + int temp_max_pa_warn_limit; + int temp_min_pa_warn_limit; + int temp_max_pa_sever_limit; + int temp_min_pa_sever_limit; + int temp_max_board_warn_limit; + int temp_min_board_warn_limit; + int temp_max_board_sever_limit; + int temp_min_board_sever_limit; + int pa_power; + int slave_power_act; + int master_power_act; + int pa_power_act; + int temp_pa_cur; + int temp_board_cur; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); @@ -43,6 +71,10 @@ void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); +int sendto_osmobts(struct uc *ucontrol, enum sbts2050_alert_lvl alert, + enum sbts2050_temp_sensor sensor, + struct sbts2050_config_info *add_info); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { -- 1.7.10.4 From holger at freyther.de Wed Mar 26 18:59:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 26 Mar 2014 19:59:03 +0100 Subject: [osmo-bts PATCH] src: Add OML support for sending failure message from manager In-Reply-To: <1395850236-6570-1-git-send-email-anayuso@sysmocom.de> References: <1395850236-6570-1-git-send-email-anayuso@sysmocom.de> Message-ID: <20140326185903.GB11354@xiaoyu.lan> On Wed, Mar 26, 2014 at 05:10:36PM +0100, Alvaro Neira Ayuso wrote: Dear Alvaro, is that anolder patch? > +static int read_unix_sock(struct osmo_fd *fd, unsigned int what) > +{ ... the connection should remain open, you should probably use the IPA multiplex protocol here (or use sequential packet mode). > +struct sbts2050_config_info confinfo; make this static > +#define OM_ALLOC_SIZE 1024 > +#define OM_HEADROOM_SIZE 128 > +#define SOCKET_PATH "/tmp/echo_temp" Why /tmp/echo_temp? In general we might want to not have this in a public writable directory? > + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) > + goto err; Can't you remember the TRX_NR? We don't really want to read the EEPROM all the time? > + strcpy(version, PACKAGE_VERSION); neat idea! From anayuso at sysmocom.de Mon Mar 31 09:52:07 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Mon, 31 Mar 2014 11:52:07 +0200 Subject: [osmo-bts PATCH v2] src: Add OML support for sending failure message from manager In-Reply-To: <1395850236-6570-1-git-send-email-anayuso@sysmocom.de> References: <1395850236-6570-1-git-send-email-anayuso@sysmocom.de> Message-ID: <1396259527-11008-1-git-send-email-anayuso@sysmocom.de> From: ?lvaro Neira Ayuso With this patch, the manager monitors the sensors and send OML Failure message from the Manager to the BTS and the BTS to BSC, for having a report system of the sensors. Signed-off-by: Alvaro Neira Ayuso --- v2: Added IPA header in the communication between MGR and the BTS program. Change the socket function for keeping it open. Fixed some errors when I had used the msgb functions for creating the OML message. src/osmo-bts-sysmo/main.c | 65 ++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 77 +++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 140 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_misc.h | 33 ++++++++ 4 files changed, 314 insertions(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 74ee47f..643840a 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -45,8 +46,10 @@ #include #include #include +#include #define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock" +#define SOCKET_PATH "/dev/echo_temp" #include "utils.h" #include "eeprom.h" @@ -258,6 +261,7 @@ static void signal_handler(int signal) case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); bts_shutdown(bts, "SIGINT"); + unlink(SOCKET_PATH); break; case SIGABRT: case SIGUSR1: @@ -288,6 +292,55 @@ static int write_pid_file(char *procname) return 0; } +static int read_sock(struct osmo_fd *fd, unsigned int what) +{ + struct msgb *msg; + struct gsm_abis_mo *mo; + int rc; + + msg = oml_msgb_alloc(); + if (msg == NULL) + return -1; + + rc = recv(fd->fd, msg->tail, msg->data_len, 0); + if (rc <= 0) { + close(fd->fd); + osmo_fd_unregister(fd); + return -1; + } + + msgb_put(msg, rc); + + /*Remove the IPA header for removing the conflict with the new IPA + * header*/ + msgb_pull(msg, sizeof(struct ipaccess_head *)-1); + + mo = &bts->mo; + msg->trx = mo->bts->c0; + msg->l2h = msg->data; + msg->l3h = msg->data + sizeof(struct abis_om_fom_hdr); + + return abis_oml_sendmsg(msg); +} + +static int accept_unix_sock(struct osmo_fd *fd, unsigned int what) +{ + int sfd = fd->fd, cl; + struct osmo_fd *ofd = (struct osmo_fd *)fd->data; + + cl = accept(sfd, NULL, NULL); + if (cl < 0) + return -1; + + ofd->fd = cl; + if (osmo_fd_register(ofd) != 0) { + close(cl); + return -1; + } + + return 0; +} + int main(int argc, char **argv) { struct stat st; @@ -295,6 +348,7 @@ int main(int argc, char **argv) struct gsm_bts_role_bts *btsb; struct e1inp_line *line; void *tall_msgb_ctx; + struct osmo_fd fd, rfd; int rc; tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); @@ -370,6 +424,17 @@ int main(int argc, char **argv) fprintf(stderr, "unable to connect to BSC\n"); exit(1); } + fd.cb = accept_unix_sock; + rfd.cb = read_sock; + rfd.when = BSC_FD_READ; + fd.data = &rfd; + + rc = osmo_sock_unix_init_ofd(&fd, SOCK_SEQPACKET, 0, SOCKET_PATH, + OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); + if (rc < 0) { + perror("Error creating socket domain creation"); + exit(3); + } if (daemonize) { rc = osmo_daemonize(); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 6c64d0f..c8b4f02 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -47,7 +48,11 @@ static int no_eeprom_write = 0; static int daemonize = 0; +static int trx_nr = -1; +static int fd_unix = -1; +static int state_connection = 0; void *tall_mgr_ctx; +static struct sbts2050_config_info confinfo; /* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */ #define TEMP_TIMER_SECS (6 * 3600) @@ -55,7 +60,29 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +/* every 5 minutes try to reconnect if we have a problem in the communication*/ +#define CONNECT_TIMER_SECS (300) + +/* unix domain socket file descriptor */ +#define SOCKET_PATH "/dev/echo_temp" + #ifdef BUILD_SBTS2050 +static struct osmo_timer_list connect_timer; +static void socket_connect_cb(void *data) +{ + if (state_connection == 0) { + fd_unix = osmo_sock_unix_init(SOCK_SEQPACKET, 0, SOCKET_PATH, + OSMO_SOCK_F_CONNECT); + if (fd_unix < 0) { + LOGP(DTEMP, LOGL_ERROR, "Error creating unix socket\n"); + return; + } + + state_connection = 1; + } + osmo_timer_schedule(&connect_timer, CONNECT_TIMER_SECS, 0); +} + static struct osmo_timer_list temp_uc_timer; static void check_uctemp_timer_cb(void *data) { @@ -64,6 +91,50 @@ static void check_uctemp_timer_cb(void *data) sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); + confinfo.temp_pa_cur = temp_pa; + confinfo.temp_board_cur = temp_board; + + if (confinfo.temp_min_pa_warn_limit > temp_pa || + confinfo.temp_max_pa_warn_limit < temp_pa) { + state_connection = sendto_osmobts(fd_unix, ucontrol0, + SBTS2050_WARN_ALERT, + SBTS2050_TEMP_PA, + &confinfo, trx_nr); + } else if (confinfo.temp_min_pa_sever_limit > temp_pa || + confinfo.temp_max_pa_sever_limit < temp_pa) { + state_connection = sendto_osmobts(fd_unix, ucontrol0, + SBTS2050_SEVER_ALERT, + SBTS2050_TEMP_PA, + &confinfo, trx_nr); + sbts2050_uc_power(ucontrol0, + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_MASTER), + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_SLAVE), + confinfo.pa_power_act); + } + + if (confinfo.temp_min_board_warn_limit > temp_board || + confinfo.temp_max_board_warn_limit < temp_board) { + state_connection = sendto_osmobts(fd_unix, ucontrol0, + SBTS2050_WARN_ALERT, + SBTS2050_TEMP_BOARD, + &confinfo, trx_nr); + } else if (confinfo.temp_min_board_sever_limit > temp_board || + confinfo.temp_max_board_sever_limit < temp_board) { + state_connection = sendto_osmobts(fd_unix, ucontrol0, + SBTS2050_SEVER_ALERT, + SBTS2050_TEMP_BOARD, + &confinfo, trx_nr); + sbts2050_uc_power(ucontrol0, confinfo.master_power_act, + confinfo.slave_power_act, + sbts2050_uc_status(ucontrol0, + SBTS2050_STATUS_PA)); + } + + if (state_connection == 0) + close(fd_unix); + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); } #endif @@ -93,6 +164,7 @@ static void initialize_sbts2050(void) if (val != 0) return; } + trx_nr = val; ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); if (ucontrol0.fd < 0) { @@ -169,6 +241,7 @@ static void signal_handler(int signal) case SIGINT: sysmobts_check_temp(no_eeprom_write); sysmobts_update_hours(no_eeprom_write); + close(fd_unix); exit(0); break; case SIGABRT: @@ -363,6 +436,10 @@ int main(int argc, char **argv) hours_timer.cb = hours_timer_cb; hours_timer_cb(NULL); + /*start handle for reconnect the socket in case of error*/ + connect_timer.cb = socket_connect_cb; + socket_connect_cb(NULL); + /* start uc temperature check timer */ initialize_sbts2050(); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 9ea26c2..0e89da6 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -29,13 +29,17 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include +#include #include "btsconfig.h" #include "sysmobts_misc.h" @@ -49,10 +53,144 @@ #define SERIAL_ALLOC_SIZE 300 #define SIZE_HEADER_RSP 5 #define SIZE_HEADER_CMD 4 - +#define OM_ALLOC_SIZE 1024 +#define OM_HEADROOM_SIZE 128 +#define IPA_OML_PROTO 0xFF #ifdef BUILD_SBTS2050 /********************************************************************** + * Function send information to OsmoBts + *********************************************************************/ +static void add_sw_descr(struct msgb *msg) +{ + char file_version[255]; + char file_id[255]; + + strcpy(file_id, "sysmomgr"); + strncpy(file_version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)); + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, strlen(file_id), + (uint8_t *)file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, strlen(file_version), + (uint8_t *)file_version); +} + +static void add_probable_cause(struct msgb *msg) +{ + msgb_tv_put(msg, NM_ATT_PROB_CAUSE, NM_PCAUSE_T_MANUF); + msgb_v_put(msg, 0); + msgb_v_put(msg, 0); +} + +static void add_ipa_header(struct msgb *msg) +{ + struct ipaccess_head *hh; + + hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh)); + hh->proto = IPA_OML_PROTO; + hh->len = htons(msg->len); +} + +static void add_oml_hdr_msg(struct msgb *msg, uint8_t msg_type, + uint8_t obj_class, uint8_t bts_nr, + uint8_t trx_nr, uint8_t ts_nr) +{ + struct abis_om_fom_hdr *foh; + struct abis_om_hdr *omh; + + msg->l3h = msgb_push(msg, sizeof(*foh)); + foh = (struct abis_om_fom_hdr *) msg->l3h; + + foh->msg_type = msg_type; + foh->obj_class = obj_class; + foh->obj_inst.bts_nr = bts_nr; + foh->obj_inst.trx_nr = trx_nr; + foh->obj_inst.ts_nr = ts_nr; + + msg->l2h = msgb_push(msg, sizeof(*omh)); + omh = (struct abis_om_hdr *) msg->l2h; + + omh->mdisc = ABIS_OM_MDISC_FOM; + omh->placement = ABIS_OM_PLACEMENT_ONLY; + omh->sequence = 0; + omh->length = msgb_l3len(msg); +} + +int sendto_osmobts(int fd_unix, struct uc *ucontrol, + enum sbts2050_alert_lvl alert, + enum sbts2050_temp_sensor sensor, + struct sbts2050_config_info *add_info, int trx_nr) +{ + int rc; + struct msgb *msg; + const char *buf, *nsensor; + + msg = msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating oml msg\n"); + goto err; + } + + add_oml_hdr_msg(msg, NM_MT_FAILURE_EVENT_REP, 0, 0, trx_nr, 0); + + msgb_tv_put(msg, NM_ATT_EVENT_TYPE, NM_EVT_ENV_FAIL); + + switch (alert) { + case SBTS2050_WARN_ALERT: + msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_WARNING); + break; + case SBTS2050_SEVER_ALERT: + msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_CRITICAL); + break; + default: + goto err; + } + + add_probable_cause(msg); + + add_sw_descr(msg); + + switch (sensor) { + case SBTS2050_TEMP_BOARD: + buf = "Unusual temperature on the Board"; + nsensor = "Board"; + break; + case SBTS2050_TEMP_PA: + buf = "Unusual temperature on the PA"; + nsensor = "PA"; + break; + default: + return -1; + } + memset(add_info->name_sensor, 0, sizeof(add_info->name_sensor)); + strncpy(add_info->name_sensor, nsensor, strlen(nsensor)); + + msgb_tl16v_put(msg, NM_ATT_ADD_TEXT, strlen(buf), (const uint8_t *)buf); + + /*If we need to send this structure to other machine, we need to pass + the integer inside the structure to internet format (big endian)*/ + msgb_tl16v_put(msg, NM_ATT_ADD_INFO, + sizeof(struct sbts2050_config_info), + (const uint8_t *)add_info); + + add_ipa_header(msg); + + rc = send(fd_unix, msg->data, msg->len, 0); + if (rc < 0) { + LOGP(DTEMP, LOGL_ERROR, "Error writting in unix socket\n"); + close(fd_unix); + msgb_free(msg); + return 0; + } + + msgb_free(msg); + return 1; +err: + msgb_free(msg); + return -1; +} + +/********************************************************************** * Functions read/write from serial interface *********************************************************************/ static int hand_serial_read(int fd, struct msgb *msg, int numbytes) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 01878f2..b19606e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -32,6 +32,34 @@ struct ucinfo { int pa; }; +enum sbts2050_alert_lvl { + SBTS2050_WARN_ALERT, + SBTS2050_SEVER_ALERT +}; + +enum sbts2050_temp_sensor { + SBTS2050_TEMP_BOARD, + SBTS2050_TEMP_PA +}; + +struct sbts2050_config_info { + char name_sensor[8]; + int temp_max_pa_warn_limit; + int temp_min_pa_warn_limit; + int temp_max_pa_sever_limit; + int temp_min_pa_sever_limit; + int temp_max_board_warn_limit; + int temp_min_board_warn_limit; + int temp_max_board_sever_limit; + int temp_min_board_sever_limit; + int pa_power; + int slave_power_act; + int master_power_act; + int pa_power_act; + int temp_pa_cur; + int temp_board_cur; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); @@ -43,6 +71,11 @@ void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); +int sendto_osmobts(int fd_unix, struct uc *ucontrol, + enum sbts2050_alert_lvl alert, + enum sbts2050_temp_sensor sensor, + struct sbts2050_config_info *add_info, int trx_nr); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { -- 1.7.10.4 From dwillmann at sysmocom.de Wed Mar 26 22:30:43 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 23:30:43 +0100 Subject: Implement gsm340_{gen_,}scts() without using tm_gmtoff Message-ID: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> Hello, this patch series depends on two patches from Alexander (once they sign handling is fixed): sms: Fix gsm340_scts() to correctly decode absolute valid times. sms: Fix support of negative timezone offsets in gsm340_gen_scts(). The first patch adds a test case to check that gsm340_scts is the inverse of gsm340_gen_scts. The next patches add a helper function to calculate the gmt offset and use those in the *_scts functions. The helper function is somewhat ugly, but it is the only portable way I could find to get the GMT offset. Ideas welcome Regards, Daniel -- - 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 dwillmann at sysmocom.de Wed Mar 26 22:30:44 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 23:30:44 +0100 Subject: [PATCH 1/4] sms_test: Test that gsm340_scts(gsm340_gen_scts(time) == time In-Reply-To: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <64c11ccd40489136537a1d3e804c18e0d66440f4.1395872056.git.daniel@totalueberwachung.de> gsm340_scts() needs to be the inverse of gsm340_gen_scts() Test different timezones and iterate through a whole year (2013) in 30 min steps. Record the current test result --- tests/sms/sms_test.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/sms/sms_test.ok | 20 +++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c index cdd4158..8b19760 100644 --- a/tests/sms/sms_test.c +++ b/tests/sms/sms_test.c @@ -268,6 +268,64 @@ static void test_gen_oa(void) printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len)); } +const char *tz_list[] = { + "UTC", + "Europe/London", + "Europe/Berlin", + "Europe/Athens", + "Europe/Moscow", + "Canada/Central", + "America/New_York", + "America/Los_Angeles", + NULL +}; + +static int test_scts_id_one_tz(void) +{ + uint8_t scts[7]; + time_t ts, ts_res, start_ts, end_ts; + + /* 2013-01-01 00:00:00 - 2014-01-01 01:00:00 increment in 30min steps */ + start_ts = 1356998400; + end_ts = 1388538000; + for (ts = start_ts; ts <= end_ts; ts += 1800) { + memset(scts, 0, sizeof(scts)); + gsm340_gen_scts(scts, ts); + ts_res = gsm340_scts(scts); + + if (ts_res != ts) { + printf("%li -> %s -> %li\n", ts, + osmo_hexdump_nospc(scts, sizeof(scts)), ts_res); + return ts; + } + } + return 0; +} + +static void test_scts_id(void) +{ + int i; + time_t ts; + const char *tz; + char *old_tz = getenv("TZ"); + + for (i = 0; ;i++) { + tz = tz_list[i]; + if (!tz) + break; + + printf("Testing gsm340_scts(gsm340_gen_scts(ts)) == ts " + "for TZ %s\n", tz); + setenv("TZ", tz, 1); + tzset(); + + ts = test_scts_id_one_tz(); + if (ts) + printf("Timezone %s failed at ts %li\n", tz, ts); + } + setenv("TZ", old_tz, 1); +} + int main(int argc, char** argv) { printf("SMS testing\n"); @@ -414,6 +472,7 @@ int main(int argc, char** argv) test_octet_return(); test_gen_oa(); + test_scts_id(); printf("OK\n"); return 0; diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok index fa536ea..a3d816c 100644 --- a/tests/sms/sms_test.ok +++ b/tests/sms/sms_test.ok @@ -26,4 +26,24 @@ Result: len(12) data(14 a1 21 43 65 87 09 21 43 65 87 19 ) Result: len(2) data(00 91 ) Result: len(9) data(0e d0 4f 78 d9 2d 9c 0e 01 ) Result: len(12) data(14 d0 4f 78 d9 2d 9c 0e c3 e2 31 19 ) +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ UTC +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/London +1364691600 -> 31301310000000 -> 1364695200 +Timezone Europe/London failed at ts 1364691600 +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Berlin +1364695200 -> 31301320000000 -> 1364698800 +Timezone Europe/Berlin failed at ts 1364695200 +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Athens +1364698800 -> 31301330000000 -> 1364702400 +Timezone Europe/Athens failed at ts 1364698800 +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Moscow +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Canada/Central +1362880800 -> 31300120000000 -> 1362884400 +Timezone Canada/Central failed at ts 1362880800 +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/New_York +1362880800 -> 31300120000000 -> 1362884400 +Timezone America/New_York failed at ts 1362880800 +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/Los_Angeles +1362880800 -> 31300120000000 -> 1362884400 +Timezone America/Los_Angeles failed at ts 1362880800 OK -- 1.8.4.2 From dwillmann at sysmocom.de Wed Mar 26 22:30:45 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 23:30:45 +0100 Subject: [PATCH 2/4] gsm0411_utils: Add helper function to get the gmt offset of a time_t In-Reply-To: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <96a6779baa1e1cc8bc1c05ce824928bbe7d240ed.1395872056.git.daniel@totalueberwachung.de> The function uses localtime as well as gmtime to calculate the timezone offset at a specific time. This is useful for the *_scts functions so we're not dependent on non-portable features (tm_gmtoff). --- src/gsm/gsm0411_utils.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index ad9753e..d857e41 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -72,6 +72,24 @@ uint8_t gsm411_unbcdify(uint8_t value) return ret; } +/* Figure out the timezone offset in a portable way. + * The idea is to convert the time_t into local and UTC struct tm + * representations and then calculate the difference of both. */ +static time_t gmtoffset_from_ts(time_t time) +{ + struct tm tm_local, tm_utc; + time_t ts_local, ts_utc; + + localtime_r(&time, &tm_local); + gmtime_r(&time, &tm_utc); + tm_utc.tm_isdst = 0; + tm_local.tm_isdst = 0; + ts_utc = mktime(&tm_utc); + ts_local = mktime(&tm_local); + + return ts_local - ts_utc; +} + /* Generate 03.40 TP-SCTS */ void gsm340_gen_scts(uint8_t *scts, time_t time) { -- 1.8.4.2 From dwillmann at sysmocom.de Wed Mar 26 22:30:46 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 23:30:46 +0100 Subject: [PATCH 3/4] gsm0411_utils: Fix timezone offs calculation in gsm340_gen_scts() In-Reply-To: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <5e1c4810acada891fc3bdd36b5d49b03293ad7db.1395872056.git.daniel@totalueberwachung.de> The current code uses gmtime which returns the time in UTC. This is not the intended behaviour (otherwise the offset could always be set to zero). Iinstead of relying on tm_gmtoff this patch uses the (portable) gmtoffset_from_ts() function to determine the current time offset. Update the test with the expected result --- src/gsm/gsm0411_utils.c | 33 +++++++++++++++++---------------- tests/sms/sms_test.ok | 12 ------------ 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index d857e41..c6d68bd 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -93,23 +93,24 @@ static time_t gmtoffset_from_ts(time_t time) /* Generate 03.40 TP-SCTS */ void gsm340_gen_scts(uint8_t *scts, time_t time) { - struct tm *tm = gmtime(&time); - - *scts++ = gsm411_bcdify(tm->tm_year % 100); - *scts++ = gsm411_bcdify(tm->tm_mon + 1); - *scts++ = gsm411_bcdify(tm->tm_mday); - *scts++ = gsm411_bcdify(tm->tm_hour); - *scts++ = gsm411_bcdify(tm->tm_min); - *scts++ = gsm411_bcdify(tm->tm_sec); -#ifdef HAVE_TM_GMTOFF_IN_TM - if (tm->tm_gmtoff >= 0) - *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15)); + struct tm tm; + time_t gmtoffset; + + localtime_r(&time, &tm); + + *scts++ = gsm411_bcdify(tm.tm_year % 100); + *scts++ = gsm411_bcdify(tm.tm_mon + 1); + *scts++ = gsm411_bcdify(tm.tm_mday); + *scts++ = gsm411_bcdify(tm.tm_hour); + *scts++ = gsm411_bcdify(tm.tm_min); + *scts++ = gsm411_bcdify(tm.tm_sec); + + gmtoffset = gmtoffset_from_ts(time); + + if (gmtoffset >= 0) + *scts++ = gsm411_bcdify(gmtoffset/(60*15)); else - *scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x08; -#else -#warning find a portable way to obtain timezone offset - *scts++ = 0; -#endif + *scts++ = gsm411_bcdify(-gmtoffset/(60*15)) | 0x08; } /* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */ diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok index a3d816c..a779f12 100644 --- a/tests/sms/sms_test.ok +++ b/tests/sms/sms_test.ok @@ -28,22 +28,10 @@ Result: len(9) data(0e d0 4f 78 d9 2d 9c 0e 01 ) Result: len(12) data(14 d0 4f 78 d9 2d 9c 0e c3 e2 31 19 ) Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ UTC Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/London -1364691600 -> 31301310000000 -> 1364695200 -Timezone Europe/London failed at ts 1364691600 Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Berlin -1364695200 -> 31301320000000 -> 1364698800 -Timezone Europe/Berlin failed at ts 1364695200 Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Athens -1364698800 -> 31301330000000 -> 1364702400 -Timezone Europe/Athens failed at ts 1364698800 Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/Moscow Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Canada/Central -1362880800 -> 31300120000000 -> 1362884400 -Timezone Canada/Central failed at ts 1362880800 Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/New_York -1362880800 -> 31300120000000 -> 1362884400 -Timezone America/New_York failed at ts 1362880800 Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ America/Los_Angeles -1362880800 -> 31300120000000 -> 1362884400 -Timezone America/Los_Angeles failed at ts 1362880800 OK -- 1.8.4.2 From dwillmann at sysmocom.de Wed Mar 26 22:30:47 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Wed, 26 Mar 2014 23:30:47 +0100 Subject: [PATCH 4/4] gsm0411_utils: Use portable helper gmtoffset_from_ts helper in gsm340_scts In-Reply-To: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> Message-ID: Avoid depending on the presence of tm_gmtoff to calculate the gmt offset. --- src/gsm/gsm0411_utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c index c6d68bd..94d48fd 100644 --- a/src/gsm/gsm0411_utils.c +++ b/src/gsm/gsm0411_utils.c @@ -119,7 +119,7 @@ time_t gsm340_scts(uint8_t *scts) struct tm tm; uint8_t yr, tz; int ofs; - time_t timestamp; + time_t timestamp, gmtoffset; memset(&tm, 0x00, sizeof(struct tm)); @@ -151,12 +151,12 @@ time_t gsm340_scts(uint8_t *scts) if (timestamp < 0) return -1; + gmtoffset = gmtoffset_from_ts(timestamp); + /* Take into account timezone offset */ timestamp -= ofs; -#ifdef HAVE_TM_GMTOFF_IN_TM /* Remove an artificial timezone offset, introduced by mktime() */ - timestamp += tm.tm_gmtoff; -#endif + timestamp += gmtoffset; return timestamp; } -- 1.8.4.2 From alexander.chemeris at gmail.com Thu Mar 27 05:21:57 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 27 Mar 2014 09:21:57 +0400 Subject: [PATCH 1/4] sms_test: Test that gsm340_scts(gsm340_gen_scts(time) == time In-Reply-To: <64c11ccd40489136537a1d3e804c18e0d66440f4.1395872056.git.daniel@totalueberwachung.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> <64c11ccd40489136537a1d3e804c18e0d66440f4.1395872056.git.daniel@totalueberwachung.de> Message-ID: Hi Daniel, On Thu, Mar 27, 2014 at 2:30 AM, Daniel Willmann wrote: > +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ UTC > +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/London > +1364691600 -> 31301310000000 -> 1364695200 > +Timezone Europe/London failed at ts 1364691600 A quick question - why does it says "failed" here? If it's ok, than we should change the wording of the message, I think. If it's not ok, we should not add this to "sms_test.ok". Right now it's confusing. -- Regards, Alexander Chemeris. CEO, Fairwaves, Inc. https://fairwaves.co From dwillmann at sysmocom.de Thu Mar 27 20:18:25 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Thu, 27 Mar 2014 21:18:25 +0100 Subject: [PATCH 1/4] sms_test: Test that gsm340_scts(gsm340_gen_scts(time) == time In-Reply-To: References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> <64c11ccd40489136537a1d3e804c18e0d66440f4.1395872056.git.daniel@totalueberwachung.de> Message-ID: <20140327201825.GF31519@adrastea.totalueberwachung.de> Hi Alexander, On Thu, 2014-03-27 at 09:21, Alexander Chemeris wrote: > On Thu, Mar 27, 2014 at 2:30 AM, Daniel Willmann wrote: > > +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ UTC > > +Testing gsm340_scts(gsm340_gen_scts(ts)) == ts for TZ Europe/London > > +1364691600 -> 31301310000000 -> 1364695200 > > +Timezone Europe/London failed at ts 1364691600 > > A quick question - why does it says "failed" here? > > If it's ok, than we should change the wording of the message, I think. > If it's not ok, we should not add this to "sms_test.ok". Right now > it's confusing. you're right. I was trying to first record the status quo so you can see the behaviour changes as the issue is fixed. Holger was quite fond of this in the recent lapdm fixes, but it probably makes less sense here. Holger, any preferences how I should handle this? Move the test to the end, have a failing test, ..? Regard, Daniel -- - 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 holger at freyther.de Fri Mar 28 08:16:37 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 28 Mar 2014 09:16:37 +0100 Subject: [PATCH 1/4] sms_test: Test that gsm340_scts(gsm340_gen_scts(time) == time In-Reply-To: <20140327201825.GF31519@adrastea.totalueberwachung.de> References: <1395873047-28229-1-git-send-email-dwillmann@sysmocom.de> <64c11ccd40489136537a1d3e804c18e0d66440f4.1395872056.git.daniel@totalueberwachung.de> <20140327201825.GF31519@adrastea.totalueberwachung.de> Message-ID: <20140328081637.GB30592@xiaoyu.lan> On Thu, Mar 27, 2014 at 09:18:25PM +0100, Daniel Willmann wrote: > you're right. I was trying to first record the status quo so you can see > the behaviour changes as the issue is fixed. > > Holger was quite fond of this in the recent lapdm fixes, but it probably > makes less sense here. Holger, any preferences how I should handle this? > Move the test to the end, have a failing test, ..? The question is if you want to have a known issue in new code or not. What is the impact for the end-user/NITB? How will this fail? Is this a step backward compared to the extensions by BSD/Linux? holger From openbsc-bounces at lists.osmocom.org Thu Mar 27 07:00:25 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Thu, 27 Mar 2014 08:00:25 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From openbsc-bounces at lists.osmocom.org Fri Mar 28 07:00:12 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Fri, 28 Mar 2014 08:00:12 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From mailman-bounces at lists.osmocom.org Fri Mar 28 08:00:08 2014 From: mailman-bounces at lists.osmocom.org (mailman-bounces at lists.osmocom.org) Date: Fri, 28 Mar 2014 09:00:08 +0100 Subject: OpenBSC unsubscribe notification Message-ID: rajeevvats at coraltele.com has been removed from OpenBSC. From sguptaau at gmail.com Fri Mar 28 09:41:10 2014 From: sguptaau at gmail.com (Sahil Gupta) Date: Fri, 28 Mar 2014 20:41:10 +1100 Subject: Fwd: OpenBSC and Roaming In-Reply-To: References: Message-ID: Hi there, I'm fairly new to the mobile world and am still coming to terms with a whole new world of terminologies. The project is to test out a theory in my lab before wanting to scale this at a larger level for commercial purposes. The intent is to be able to have roaming available with a roaming aggregator in the United States with a small-scale mobile network enabled using OpenSource software. We are probably looking at implementing no more than 15 BTS's nationwide to attract roaming customers at high traffic locations. Our roaming aggregator would like us to send them MAP SS7 Messages from our MSC. My understanding of the requirements so far are: 1 x BTS (this could be a PC with some radio cards or something like a nanoBTS) 1 x MSC/BSC/VLR We won't be issuing any sim cards on our own network in the long run and hence I don't see the point in us having a unique HLR. Are there any gurus here that would be willing to share their intelligence? -- Thanks, Sahil -- Thanks, Sahil -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Fri Mar 28 10:33:17 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Fri, 28 Mar 2014 11:33:17 +0100 Subject: OpenBSC and Roaming In-Reply-To: References: Message-ID: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> One question.how do you want to attract those mobiles? Usually high traffic locations offer high field strength of all providers, and no mobile phone has the need to search for a different network, unless it is already roaming and suddenly sees its home network. Ralph. From: openbsc-bounces at lists.osmocom.org [mailto:openbsc-bounces at lists.osmocom.org] On Behalf Of Sahil Gupta Sent: Friday, March 28, 2014 10:41 AM To: openbsc at lists.osmocom.org Subject: Fwd: OpenBSC and Roaming Hi there, I'm fairly new to the mobile world and am still coming to terms with a whole new world of terminologies. The project is to test out a theory in my lab before wanting to scale this at a larger level for commercial purposes. The intent is to be able to have roaming available with a roaming aggregator in the United States with a small-scale mobile network enabled using OpenSource software. We are probably looking at implementing no more than 15 BTS's nationwide to attract roaming customers at high traffic locations. Our roaming aggregator would like us to send them MAP SS7 Messages from our MSC. My understanding of the requirements so far are: 1 x BTS (this could be a PC with some radio cards or something like a nanoBTS) 1 x MSC/BSC/VLR We won't be issuing any sim cards on our own network in the long run and hence I don't see the point in us having a unique HLR. Are there any gurus here that would be willing to share their intelligence? -- Thanks, Sahil -- Thanks, Sahil -------------- next part -------------- An HTML attachment was scrubbed... URL: From sguptaau at gmail.com Fri Mar 28 10:37:48 2014 From: sguptaau at gmail.com (Sahil Gupta) Date: Fri, 28 Mar 2014 21:37:48 +1100 Subject: OpenBSC and Roaming In-Reply-To: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> References: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> Message-ID: Hi there, If we take the airport for example, there are two other major mobile providers offering services there. I'd probably offer free Wifi provided the customer dials a particular number after signing onto our network in order to receive a sign-on code by SMS. I know StarHub did this for years in Singapore and I always ended up roaming on their network. The other thing we would do is oviously have substantially lower costs on our network as opposed to others in order to encourage mobile providers to have our network as part of the list. Cheers, Sahil On 28 March 2014 21:33, Ralph A. Schmid, dk5ras wrote: > One question...how do you want to attract those mobiles? Usually high > traffic locations offer high field strength of all providers, and no mobile > phone has the need to search for a different network, unless it is already > roaming and suddenly sees its home network. > > > > Ralph. > > > > > > *From:* openbsc-bounces at lists.osmocom.org [mailto: > openbsc-bounces at lists.osmocom.org] *On Behalf Of *Sahil Gupta > *Sent:* Friday, March 28, 2014 10:41 AM > *To:* openbsc at lists.osmocom.org > *Subject:* Fwd: OpenBSC and Roaming > > > > Hi there, > > I'm fairly new to the mobile world and am still coming to terms with a > whole new world of terminologies. The project is to test out a theory in > my lab before wanting to scale this at a larger level for commercial > purposes. > > > > The intent is to be able to have roaming available with a roaming > aggregator in the United States with a small-scale mobile network enabled > using OpenSource software. > > > > We are probably looking at implementing no more than 15 BTS's nationwide > to attract roaming customers at high traffic locations. > > > > Our roaming aggregator would like us to send them MAP SS7 Messages from > our MSC. > > > > My understanding of the requirements so far are: > > 1 x BTS (this could be a PC with some radio cards or something like a > nanoBTS) > > 1 x MSC/BSC/VLR > > > > We won't be issuing any sim cards on our own network in the long run and > hence I don't see the point in us having a unique HLR. > > > > Are there any gurus here that would be willing to share their intelligence? > > > > > -- > Thanks, > > Sahil > > > > > > -- > Thanks, > > Sahil > -- Thanks, Sahil -------------- next part -------------- An HTML attachment was scrubbed... URL: From nikpakar at gmail.com Fri Mar 28 12:17:09 2014 From: nikpakar at gmail.com (Nik Pakar) Date: Fri, 28 Mar 2014 17:47:09 +0530 Subject: OpenBSC and Roaming In-Reply-To: References: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> Message-ID: Hello Sahil, Other than the network elements you need to do this, you will have a major hurdle in getting into the actual roaming world. Unless you are a legitimate MNO or MVNO with your own MNC, point codes in ss7 world, last but not least be a member of GSMA. Have you studied all these ? Are you trying to implement a standalone network to facilitate this ? Who is the provider willing to extend you roaming ? Is it a GRX or a MNO ? Do you have your own MNC and point codes ? Put some more info so we can see how best you can get this done. cheers. Nik On Fri, Mar 28, 2014 at 4:07 PM, Sahil Gupta wrote: > Hi there, > If we take the airport for example, there are two other major mobile > providers offering services there. > > I'd probably offer free Wifi provided the customer dials a particular > number after signing onto our network in order to receive a sign-on code by > SMS. I know StarHub did this for years in Singapore and I always ended up > roaming on their network. > > The other thing we would do is oviously have substantially lower costs on > our network as opposed to others in order to encourage mobile providers to > have our network as part of the list. > > Cheers, > Sahil > > > On 28 March 2014 21:33, Ralph A. Schmid, dk5ras wrote: > >> One question...how do you want to attract those mobiles? Usually high >> traffic locations offer high field strength of all providers, and no mobile >> phone has the need to search for a different network, unless it is already >> roaming and suddenly sees its home network. >> >> >> >> Ralph. >> >> >> >> >> >> *From:* openbsc-bounces at lists.osmocom.org [mailto: >> openbsc-bounces at lists.osmocom.org] *On Behalf Of *Sahil Gupta >> *Sent:* Friday, March 28, 2014 10:41 AM >> *To:* openbsc at lists.osmocom.org >> *Subject:* Fwd: OpenBSC and Roaming >> >> >> >> Hi there, >> >> I'm fairly new to the mobile world and am still coming to terms with a >> whole new world of terminologies. The project is to test out a theory in >> my lab before wanting to scale this at a larger level for commercial >> purposes. >> >> >> >> The intent is to be able to have roaming available with a roaming >> aggregator in the United States with a small-scale mobile network enabled >> using OpenSource software. >> >> >> >> We are probably looking at implementing no more than 15 BTS's nationwide >> to attract roaming customers at high traffic locations. >> >> >> >> Our roaming aggregator would like us to send them MAP SS7 Messages from >> our MSC. >> >> >> >> My understanding of the requirements so far are: >> >> 1 x BTS (this could be a PC with some radio cards or something like a >> nanoBTS) >> >> 1 x MSC/BSC/VLR >> >> >> >> We won't be issuing any sim cards on our own network in the long run and >> hence I don't see the point in us having a unique HLR. >> >> >> >> Are there any gurus here that would be willing to share their >> intelligence? >> >> >> >> >> -- >> Thanks, >> >> Sahil >> >> >> >> >> >> -- >> Thanks, >> >> Sahil >> > > > > -- > Thanks, > Sahil > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sguptaau at gmail.com Fri Mar 28 12:18:55 2014 From: sguptaau at gmail.com (Sahil Gupta) Date: Fri, 28 Mar 2014 23:18:55 +1100 Subject: OpenBSC and Roaming In-Reply-To: References: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> Message-ID: Hi there, We have an agreement with a MNO that is willing do handle what you raise. I always knew we wanted to remain focused on building the network and maintaining rather than the relationships in the roaming world. That part has been sorted a long time ago :-) On 28 March 2014 23:17, Nik Pakar wrote: > Hello Sahil, > > Other than the network elements you need to do this, you will have a major > hurdle in getting into the actual roaming world. Unless you are a > legitimate MNO or MVNO with your own MNC, point codes in ss7 world, last > but not least be a member of GSMA. Have you studied all these ? > > Are you trying to implement a standalone network to facilitate this ? > > Who is the provider willing to extend you roaming ? Is it a GRX or a MNO ? > > Do you have your own MNC and point codes ? > > Put some more info so we can see how best you can get this done. > > cheers. > Nik > > > On Fri, Mar 28, 2014 at 4:07 PM, Sahil Gupta wrote: > >> Hi there, >> If we take the airport for example, there are two other major mobile >> providers offering services there. >> >> I'd probably offer free Wifi provided the customer dials a particular >> number after signing onto our network in order to receive a sign-on code by >> SMS. I know StarHub did this for years in Singapore and I always ended up >> roaming on their network. >> >> The other thing we would do is oviously have substantially lower costs on >> our network as opposed to others in order to encourage mobile providers to >> have our network as part of the list. >> >> Cheers, >> Sahil >> >> >> On 28 March 2014 21:33, Ralph A. Schmid, dk5ras wrote: >> >>> One question...how do you want to attract those mobiles? Usually high >>> traffic locations offer high field strength of all providers, and no mobile >>> phone has the need to search for a different network, unless it is already >>> roaming and suddenly sees its home network. >>> >>> >>> >>> Ralph. >>> >>> >>> >>> >>> >>> *From:* openbsc-bounces at lists.osmocom.org [mailto: >>> openbsc-bounces at lists.osmocom.org] *On Behalf Of *Sahil Gupta >>> *Sent:* Friday, March 28, 2014 10:41 AM >>> *To:* openbsc at lists.osmocom.org >>> *Subject:* Fwd: OpenBSC and Roaming >>> >>> >>> >>> Hi there, >>> >>> I'm fairly new to the mobile world and am still coming to terms with a >>> whole new world of terminologies. The project is to test out a theory in >>> my lab before wanting to scale this at a larger level for commercial >>> purposes. >>> >>> >>> >>> The intent is to be able to have roaming available with a roaming >>> aggregator in the United States with a small-scale mobile network enabled >>> using OpenSource software. >>> >>> >>> >>> We are probably looking at implementing no more than 15 BTS's nationwide >>> to attract roaming customers at high traffic locations. >>> >>> >>> >>> Our roaming aggregator would like us to send them MAP SS7 Messages from >>> our MSC. >>> >>> >>> >>> My understanding of the requirements so far are: >>> >>> 1 x BTS (this could be a PC with some radio cards or something like a >>> nanoBTS) >>> >>> 1 x MSC/BSC/VLR >>> >>> >>> >>> We won't be issuing any sim cards on our own network in the long run and >>> hence I don't see the point in us having a unique HLR. >>> >>> >>> >>> Are there any gurus here that would be willing to share their >>> intelligence? >>> >>> >>> >>> >>> -- >>> Thanks, >>> >>> Sahil >>> >>> >>> >>> >>> >>> -- >>> Thanks, >>> >>> Sahil >>> >> >> >> >> -- >> Thanks, >> Sahil >> > > -- Thanks, Sahil -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Sat Mar 29 17:41:58 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Sat, 29 Mar 2014 18:41:58 +0100 Subject: OpenBSC and Roaming In-Reply-To: References: <020701cf4a71$21c433a0$654c9ae0$@schmid.xxx> Message-ID: <000001cf4b76$2f5138f0$8df3aad0$@schmid.xxx> Still I do not understand. Is the first step the free wifi, that points to the GSM network, or should the GSM network point to the wifi? Ralph. From: Sahil Gupta [mailto:sguptaau at gmail.com] Sent: Friday, 28 March, 2014 11:38 To: Ralph A. Schmid, dk5ras Cc: openbsc at lists.osmocom.org Subject: Re: OpenBSC and Roaming Hi there, If we take the airport for example, there are two other major mobile providers offering services there. I'd probably offer free Wifi provided the customer dials a particular number after signing onto our network in order to receive a sign-on code by SMS. I know StarHub did this for years in Singapore and I always ended up roaming on their network. The other thing we would do is oviously have substantially lower costs on our network as opposed to others in order to encourage mobile providers to have our network as part of the list. Cheers, Sahil On 28 March 2014 21:33, Ralph A. Schmid, dk5ras wrote: One question.how do you want to attract those mobiles? Usually high traffic locations offer high field strength of all providers, and no mobile phone has the need to search for a different network, unless it is already roaming and suddenly sees its home network. Ralph. From: openbsc-bounces at lists.osmocom.org [mailto:openbsc-bounces at lists.osmocom.org] On Behalf Of Sahil Gupta Sent: Friday, March 28, 2014 10:41 AM To: openbsc at lists.osmocom.org Subject: Fwd: OpenBSC and Roaming Hi there, I'm fairly new to the mobile world and am still coming to terms with a whole new world of terminologies. The project is to test out a theory in my lab before wanting to scale this at a larger level for commercial purposes. The intent is to be able to have roaming available with a roaming aggregator in the United States with a small-scale mobile network enabled using OpenSource software. We are probably looking at implementing no more than 15 BTS's nationwide to attract roaming customers at high traffic locations. Our roaming aggregator would like us to send them MAP SS7 Messages from our MSC. My understanding of the requirements so far are: 1 x BTS (this could be a PC with some radio cards or something like a nanoBTS) 1 x MSC/BSC/VLR We won't be issuing any sim cards on our own network in the long run and hence I don't see the point in us having a unique HLR. Are there any gurus here that would be willing to share their intelligence? -- Thanks, Sahil -- Thanks, Sahil -- Thanks, Sahil -------------- next part -------------- An HTML attachment was scrubbed... URL: From openbsc-bounces at lists.osmocom.org Sat Mar 29 07:00:11 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Sat, 29 Mar 2014 08:00:11 +0100 Subject: 3 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 3 request(s) waiting for your consideration at: https://lists.osmocom.org/mailman/admindb/openbsc Please attend to this at your earliest convenience. This notice of pending requests, if any, will be sent out daily. Pending posts: From: tlab.tester at googlemail.com on Mon Mar 3 13:01:09 2014 Subject: Unsubscribe Cause: Message may contain administrivia From: zielonka.markus at googlemail.com on Mon Mar 3 15:16:07 2014 Subject: unsubscribe Cause: Message may contain administrivia From: holger at freyther.de on Thu Mar 20 21:44:00 2014 Subject: DRAFT for a 30C3 report. Care to review? Cause: Message body is too big: 1033152 bytes with a limit of 400 KB From mailman-bounces at lists.osmocom.org Sun Mar 30 07:00:06 2014 From: mailman-bounces at lists.osmocom.org (mailman-bounces at lists.osmocom.org) Date: Sun, 30 Mar 2014 09:00:06 +0200 Subject: OpenBSC unsubscribe notification Message-ID: jmho at jmho.de has been removed from OpenBSC. From jerlbeck at sysmocom.de Mon Mar 31 13:11:57 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 31 Mar 2014 15:11:57 +0200 Subject: [PATCH] oml: Pass all valid state change requests to the model Message-ID: <1396271517-7493-1-git-send-email-jerlbeck@sysmocom.de> Currently ADM state change request that tries to set the administrative state to the current value are immediately ACK'ed. Beside the caching problem, this could lead the protocol inconsistencies if two such requests are sent one after the other and the second arrives before the procedure of the first has finished. This patch removes the shortcut in oml_rx_chg_adm_state() which immediately called oml_mo_statechg_ack(mo). Ticket: OW#1132 Sponsored-by: On-Waves ehf --- src/common/oml.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/common/oml.c b/src/common/oml.c index 9ec773b..b7c12f7 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -765,11 +765,10 @@ static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg) return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); /* Step 2: Do some global dependency/consistency checking */ - if (mo->nm_state.administrative == adm_state) { - DEBUGP(DOML, "... automatic ACK, ADM state already was %s\n", - get_value_string(abis_nm_adm_state_names, adm_state)); - return oml_mo_statechg_ack(mo); - } + if (mo->nm_state.administrative == adm_state) + LOGP(DOML, LOGL_NOTICE, + "ADM state already was %s\n", + get_value_string(abis_nm_adm_state_names, adm_state)); /* Step 3: Ask BTS driver to apply the state chg */ return bts_model_chg_adm_state(bts, mo, obj, adm_state); -- 1.7.9.5 From andrew at carrierdetect.com Mon Mar 31 15:06:45 2014 From: andrew at carrierdetect.com (Andrew Back) Date: Mon, 31 Mar 2014 16:06:45 +0100 Subject: OsmoTRX on Parallella. Message-ID: I wrote a blog post about running Osmocom on Parallella, with UmTRX: http://www.rs-online.com/designspark/electronics/eng/blog/building-a-gsm-base-station-with-parallella-and-umtrx Just using the dual-core ARM in the Zynq, so nothing surprising/interesting to this list and it's more of just an intro. However, I'm curious as to opportunities for improving the performance by offloading parts of the transceiver to the Epiphany chip. Does anyone have any views on how practical this might be, effort involved and potential gains etc? Cheers, Andrew -- Andrew Back http://carrierdetect.com From wegadj at gmail.com Mon Mar 31 16:42:25 2014 From: wegadj at gmail.com (=?iso-8859-1?Q?Jes=FAs_Vega_Diaz?=) Date: Mon, 31 Mar 2014 18:42:25 +0200 Subject: SMPP + OpenBSC Message-ID: <931401DD-14B4-452B-A34C-9E0B99F0BE44@gmail.com> Hi all; I have deployed one ipaccess nanoBTS 1800, with OpenBSC (osmo-nitb) and all the osmocom suite apps. I have already make succesfully GSM calls, SMS, and GPRS/EDGE packet data connections. I now want support for sending binary SMS, i have read that with SMPP i would can. I have compiled OpenBSC with SMPP but now I don?t know how to use it, i think it is in the OpenBSC vty, but i don?t know the commands or how to use the interface. If you can give me some light in this thread i will grant you. Sorry for my English Best Regards Jes?s Vega Diaz From peter at stuge.se Mon Mar 31 16:53:02 2014 From: peter at stuge.se (Peter Stuge) Date: Mon, 31 Mar 2014 18:53:02 +0200 Subject: SMPP + OpenBSC In-Reply-To: <931401DD-14B4-452B-A34C-9E0B99F0BE44@gmail.com> References: <931401DD-14B4-452B-A34C-9E0B99F0BE44@gmail.com> Message-ID: <20140331165302.1238.qmail@stuge.se> Jes?s Vega Diaz wrote: > I have compiled OpenBSC with SMPP but now I don?t know how to use it, I believe you need an external SMSC which OpenBSC will speak SMPP to. //Peter From tele at rhizomatica.org Mon Mar 31 21:48:09 2014 From: tele at rhizomatica.org (tele) Date: Mon, 31 Mar 2014 16:48:09 -0500 Subject: SMPP + OpenBSC In-Reply-To: <931401DD-14B4-452B-A34C-9E0B99F0BE44@gmail.com> References: <931401DD-14B4-452B-A34C-9E0B99F0BE44@gmail.com> Message-ID: <20140331164809.4b774dfb@2cb> Hi, An example configuration for SMPP is the following: smpp local-tcp-port 2775 policy closed esme OSMPP password YOURPWD default-route You do need an external SMSC that binds to OpenBSC using SMPP. Please note that only SMS that are not for subscribers will go through the SMPP interface, osmo-nitb check if the extension exists in the HLR if not the SMS is sent through SMPP. You can do prefix matching but it will still apply only for numbers not in the HLR. We did a dirty workaround in order to force all the SMS through SMPP to a SMSC based on Kannel. http://cgit.osmocom.org/openbsc/commit/?h=ciaby/rhizomatica&id=112393a6109ade98b997e6bc3d221d5a2e9dd402 Kannel is configured with a TX/RX bind towards OpenBSC. You may use only a TRX. If you need help with Kannel config let me know :tele On Mon, 31 Mar 2014 18:42:25 +0200 "Jes?s Vega Diaz" wrote: > Hi all; > > I have deployed one ipaccess nanoBTS 1800, with OpenBSC (osmo-nitb) > and all the osmocom suite apps. > > I have already make succesfully GSM calls, SMS, and GPRS/EDGE packet > data connections. > > I now want support for sending binary SMS, i have read that with SMPP > i would can. > > I have compiled OpenBSC with SMPP but now I don?t know how to use it, > i think it is in the OpenBSC vty, but i don?t know the commands or > how to use the interface. > > If you can give me some light in this thread i will grant you. > > Sorry for my English > Best Regards > > Jes?s Vega Diaz