From zero-kelvin at gmx.de Mon Jan 27 22:43:03 2014 From: zero-kelvin at gmx.de (dexter) Date: Mon, 27 Jan 2014 23:43:03 +0100 Subject: UPDATE -- Osmocom Berlin User Group meeting -- NEXT MEETING In-Reply-To: <20130605121428.GA10030@nataraja.gnumonks.org> References: <502d01a9.mirider@mirider.augusta.de> <20120818115942.GV29525@prithivi.gnumonks.org> <51AF0097.10402@gmx.de> <20130605121428.GA10030@nataraja.gnumonks.org> Message-ID: <52E6E0F7.4040205@gmx.de> Hi All. It's time Again! This is the announcement for the next Osmocom Berlin meeting. Jan 29, 8pm @ CCC Berlin, Marienstr. 11, 10117 Berlin There is no formal presentation scheduled for this meeting. If you are interested to show up, feel free to do so. There is no registration required. The meeting is free as in "free beer", despite no actual free beer being around. I am looking forward to see you there! regards. Philipp From jason.anoop at gmail.com Thu Jan 2 11:26:55 2014 From: jason.anoop at gmail.com (Jason Anoop) Date: Thu, 2 Jan 2014 16:56:55 +0530 Subject: Openbsc support for new BTS In-Reply-To: <20131211001758.GB7351@nataraja.gnumonks.org> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> <20131211001758.GB7351@nataraja.gnumonks.org> Message-ID: Hello Harald, Season's greetings! I was on Christmas vacation and just back in office today. Thank you for your time and patience to respond with the details of standard message structure of osmocom coding style. I'm sorry, at this point I'm not compliant with that and surely require some effort on that front. Right now my priority was to make this piece of software work with Octasic Phy and I'm very close to that and will update you after the testing. Right now the code is not very clean as I might not have followed osmocom coding rules and needs to be cleaned up. But I'm trying to share the OSMOBTS modifications with you. As I said I'm new to git, I'm just trying by going through some tutorials. I have local folder osmo-bts which was cloned from osmocom repo git clone git://git.osmocom.org/osmo-bts.git I then changed the branch to jolly/trx from master: git checkout -b jolly/trx origin/jolly/trx I then created my private branch: git checkout -b jason-oct-phy Then I have added all my changes into it. I then added the modified files into git. git add . Then I commited the changes: git commit -m "jason-oct-phy new branch - Initial commit" Changed the author & email: git config --global user.name "Jason" git config --global user.email jason.anoop at gmail.com updated the commit to reflect the above: git commit --amend --reset-author git log shows: root at gsm-bss:/home/osmo-bts# git log commit 9bd1926c1e105844ce3e8d39234c6aec9259cc27 Author: Jason Date: Thu Jan 2 16:07:13 2014 +0530 jason-oct-phy new branch - Initial commit I can see my branch active: root at gsm-bss:/home/osmo-bts# git branch * jason-oct-phy jolly/trx master I see all my changes are commited: root at gsm-bss:/home/osmo-bts# git status # On branch jason-oct-phy nothing to commit (working directory clean) I can also see the diff between jolly/trx branch and my jason-oct-phy branch. git diff jolly/trx jason-oct-phy However, when I try to push my branch changes to the repo, I fail. root at gsm-bss:/home/osmo-bts# git push -u origin jason-oct-phy fatal: remote error: access denied or repository not exported: /osmo-bts.git Could you please help me if I'm missing something? Why am I not able to push the changes? Thanks for your help in this regard. Cheers! Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: From Jason.DSouza at octasic.com Fri Jan 17 16:11:46 2014 From: Jason.DSouza at octasic.com (Jason DSouza) Date: Fri, 17 Jan 2014 16:11:46 +0000 Subject: Openbsc support for new BTS In-Reply-To: References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> <20131211001758.GB7351@nataraja.gnumonks.org>, Message-ID: <813F249CA3F4814F9249E5253FFA7CC24DC168E4@MAIL2.octasic.com> Hello Harald, I wanted to discuss with you about two problems we are currently facing with openbsc and octasic Phy. (1) During the configuration, openbsc takes quite a long time to configure all the physical timeslots. Octasic phy configures those physical channels instantly and sends ack to openbsc but openbsc state transition takes quite a long time to send the next physical timeslot config. Is there anything we could do to make this faster? (2) In Openbsc all the physical timeslot configurations are done at one time at the beginning and during calls only logical channels are configured and released but physical timeslots are always configured. We see a lot of unexpected channels are configured because of emergency calls and intruder calls (may be surrounding disturbances). Those unwanted calls are not going through though, they create unnecessary problems. I have kept the auth policy as closed in the openbsc config. Is there any way we can avoid those unwanted logical channel configurations happening for emergency and other intruder calls ? How about the possibility of configuring physical channel configurations along with logical channel configurations on the go whenever ts is required? I understand Openbsc behavior should be modified in that case. Thanks in advance for your inputs on those. Regarding sharing of the code, as I pointed out in my last email that I'm not able to push the changes onto the branch (as in below email), I'm also fine to share the tar file containing the changes if someone can help me create a branch on git repo. Thanks, Jason ________________________________ From: Jason Anoop [jason.anoop at gmail.com] Sent: Thursday, January 02, 2014 4:56 PM To: Harald Welte Cc: openbsc at lists.osmocom.org; Jason DSouza; Amit Singh Subject: Re: Openbsc support for new BTS Hello Harald, Season's greetings! I was on Christmas vacation and just back in office today. Thank you for your time and patience to respond with the details of standard message structure of osmocom coding style. I'm sorry, at this point I'm not compliant with that and surely require some effort on that front. Right now my priority was to make this piece of software work with Octasic Phy and I'm very close to that and will update you after the testing. Right now the code is not very clean as I might not have followed osmocom coding rules and needs to be cleaned up. But I'm trying to share the OSMOBTS modifications with you. As I said I'm new to git, I'm just trying by going through some tutorials. I have local folder osmo-bts which was cloned from osmocom repo git clone git://git.osmocom.org/osmo-bts.git I then changed the branch to jolly/trx from master: git checkout -b jolly/trx origin/jolly/trx I then created my private branch: git checkout -b jason-oct-phy Then I have added all my changes into it. I then added the modified files into git. git add . Then I commited the changes: git commit -m "jason-oct-phy new branch - Initial commit" Changed the author & email: git config --global user.name "Jason" git config --global user.email jason.anoop at gmail.com updated the commit to reflect the above: git commit --amend --reset-author git log shows: root at gsm-bss:/home/osmo-bts# git log commit 9bd1926c1e105844ce3e8d39234c6aec9259cc27 Author: Jason > Date: Thu Jan 2 16:07:13 2014 +0530 jason-oct-phy new branch - Initial commit I can see my branch active: root at gsm-bss:/home/osmo-bts# git branch * jason-oct-phy jolly/trx master I see all my changes are commited: root at gsm-bss:/home/osmo-bts# git status # On branch jason-oct-phy nothing to commit (working directory clean) I can also see the diff between jolly/trx branch and my jason-oct-phy branch. git diff jolly/trx jason-oct-phy However, when I try to push my branch changes to the repo, I fail. root at gsm-bss:/home/osmo-bts# git push -u origin jason-oct-phy fatal: remote error: access denied or repository not exported: /osmo-bts.git Could you please help me if I'm missing something? Why am I not able to push the changes? Thanks for your help in this regard. Cheers! Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: From laforge at gnumonks.org Fri Jan 17 16:50:49 2014 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 17 Jan 2014 17:50:49 +0100 Subject: Openbsc support for new BTS In-Reply-To: <813F249CA3F4814F9249E5253FFA7CC24DC168E4@MAIL2.octasic.com> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> <20131211001758.GB7351@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24DC168E4@MAIL2.octasic.com> Message-ID: <20140117165049.GG10457@nataraja> Hi Jason, On Fri, Jan 17, 2014 at 04:11:46PM +0000, Jason DSouza wrote: > During the configuration, openbsc takes quite a long time to configure > all the physical timeslots. Octasic phy configures those physical > channels instantly and sends ack to openbsc but openbsc state > transition takes quite a long time to send the next physical timeslot > config. Is there anything we could do to make this faster? I don't think there are any delays in the OpenBSC codes, at least not that I remember. The OML configuration on the sysmoBTS or nanoBTS takes only seconds for a single TRX. I would appreciate if you could send a pcap file of the complete Abis dialogue betewen osmo-bts and openbsc so I can see what might be causing the delay. > In Openbsc all the physical timeslot configurations are done at one > time at the beginning and during calls only logical channels are > configured and released but physical timeslots are always configured. correct. > We see a lot of unexpected channels are configured because of > emergency calls and intruder calls (may be surrounding disturbances). I suspect this is related to the fact that the RACH detection only has a very weak CRC, which means that you get lots of false positives from the PHY. Is that the case? > Those unwanted calls are not going through though, they create > unnecessary problems. I have kept the auth policy as closed in the > openbsc config. I would strongly argue against running any 'open' network outside a faraday cage. So I believe you are doing it the 'right' way. > Is there any way we can avoid those unwanted logical channel > configurations happening for emergency and other intruder calls ? You can tune a lot of the parameters. In osmo-bts code itself, you can set a threshold in terms of RxLevel or C/I (is that available for RACH detection?) and drop all requests below a certain level or C/I In the system information, you can play with paramters such as Rx-Access-Level-Min. If you have mobile phones with engineering modes, then you can set the cell to barred in the SI and instruct your engineering mode phone to ignore barred cells. This way no real other phones would actually communicate with your cell. Finally, you can of course always use a duplexer + attenuator + coaxial cable between phone and BTS to avoid any interference from the real networks surrounding you. We have some customers who use this with cascaded splitters for up to 100 (!) mobile stations during device testing. You need phones with an antenna connector, though. > How about the possibility of configuring physical channel > configurations along with logical channel configurations on the go > whenever ts is required? I understand Openbsc behavior should be > modified in that case. This is not supported by OpenBSC so far. It is a classic BSC with static timeslot configurations. Our customers (or other production users who are not our customers) so far didn't indicate a strong need for dynamic allocation, so it is not implemented yet. And yes, it would mean some architectural changes. If there is [commercial] demand, or somebody seriously wants to contribute some time and effort in implementing it, we would apprecaite that. Otherwise it's just one of many potential wishlist items on a long list, sorry ;) > Regarding sharing of the code, as I pointed out in my last email that > I'm not able to push the changes onto the branch (as in below email), Sorry for not getting back on that. Like all Free Software projects I know of, the git repositories only provide public read access. Write access is permitted only via git-over-ssh, and we would need your ssh public key. If you send that public key by private mail to me, I can autorize you to commit to the repository. Meanwhile, and independent of that, I suggest the use of 'git send-email' on your series of commit, to generate a series of automatically generated e-mail messages to the openbsc at lists.osmocom.org mailing list for public review of the code. If you feel hesitant due to not having done this with git before: feel free to do a test run to my personal e-mail address and I'll let you know if everything has worked. > I'm also fine to share the tar file containing the changes if someone > can help me create a branch on git repo. Let's work on your git commit access and send the patch series by e-mail meanwhile. Thanks! 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 Jason.DSouza at octasic.com Tue Jan 21 12:51:41 2014 From: Jason.DSouza at octasic.com (Jason DSouza) Date: Tue, 21 Jan 2014 12:51:41 +0000 Subject: Openbsc support for new BTS In-Reply-To: <20140117165049.GG10457@nataraja> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> <20131211001758.GB7351@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24DC168E4@MAIL2.octasic.com> <20140117165049.GG10457@nataraja> Message-ID: <813F249CA3F4814F9249E5253FFA7CC24DC1695B@MAIL2.octasic.com> Hello Harald, Thanks for your inputs. On Fri, Jan 17, 2014 at 10:20 PM, Harald Welte wrote: >> During the configuration, openbsc takes quite a long time to configure all the physical timeslots. > I don't think there are any delays in the OpenBSC codes, at least not that I remember. > The OML configuration on the sysmoBTS or nanoBTS takes only seconds for a single TRX. I investigated this in osmobts. The delay was exactly 20 seconds per physical ts, thus amounting around 160 seconds approx. The reason seems to be OML_PING_TIMER of 20 sec set after LINK_STATE_CONNECT in abis_timeout() function. I guess that's the polling time for the abis messages? >> We see a lot of unexpected channels are configured > I suspect this is related to the fact that the RACH detection only has a very weak CRC, > which means that you get lots of false positives from the PHY. Is that the case? I do not think they are false positives from the phy, neither I think our CRC is weak. Those are mainly the rach from real commercial phones around. > I would strongly argue against running any 'open' network outside a faraday cage. > So I believe you are doing it the 'right' way. Of course yes! Auth policy in the config is always closed :) > You can tune a lot of the parameters. > In osmo-bts code itself, you can set a threshold in terms of RxLevel or C/I > and drop all requests below a certain level or C/I I need to check the support for those messages in our L1. > In the system information, you can play with paramters such as Rx-Access-Level-Min. The parameter rxlev access min <0-63> in the openbsc config takes care of this? But again, this is measurement information I guess and need to be supported by the phy. > Write access is permitted only via git-over-ssh, and we would need your ssh public key. > If you send that public key by private mail to me, I can autorize you to commit to the repository. Ok I will do that in the separate email. Thanks, Jason From laforge at gnumonks.org Tue Jan 21 14:04:14 2014 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 21 Jan 2014 15:04:14 +0100 Subject: Openbsc support for new BTS In-Reply-To: <813F249CA3F4814F9249E5253FFA7CC24DC1695B@MAIL2.octasic.com> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> <20131211001758.GB7351@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24DC168E4@MAIL2.octasic.com> <20140117165049.GG10457@nataraja> <813F249CA3F4814F9249E5253FFA7CC24DC1695B@MAIL2.octasic.com> Message-ID: <20140121140414.GB14476@nataraja> Hi Jason, On Tue, Jan 21, 2014 at 12:51:41PM +0000, Jason DSouza wrote: > > which means that you get lots of false positives from the PHY. Is > > that the case? > > I do not think they are false positives from the phy, neither I think > our CRC is weak. Those are mainly the rach from real commercial phones > around. I am not referring to your implementation, but to the general effects / short-comings / implications of the GSM specification. As far as I understand, you typically have lots of false positives as the CRC _inside_ the RACH burst is so weak, that applying it to random noies will still give you considerable number of hits. But yes, if you actually operate with an antenna during R&D, then you will likely see real RACH bursts of commercial phones. > > In osmo-bts code itself, you can set a threshold in terms of RxLevel > > or C/I and drop all requests below a certain level or C/I > > I need to check the support for those messages in our L1. The L1 just has to report RxLevel and C/I to osmo-bts, the rest is done in osmo-bts. > > In the system information, you can play with paramters such as > > Rx-Access-Level-Min. > > The parameter rxlev access min <0-63> in the openbsc config takes care > of this? But again, this is measurement information I guess and need > to be supported by the phy. This is a standard GSM radio parameter that will change behavior of the MS. No support required in your PHY. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From laforge at gnumonks.org Wed Jan 1 18:49:42 2014 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 1 Jan 2014 19:49:42 +0100 Subject: OsmoDevCon 2014 / Date / Venue In-Reply-To: <20131105155825.GK12353@nataraja.gnumonks.org> References: <20131105155825.GK12353@nataraja.gnumonks.org> Message-ID: <20140101184942.GM7022@nataraja.gnumonks.org> Dear all, as the December 31st registration deadline has just passed, I'm happy to announce that all 17 requests for participation have been approved. We are still below the ~20 people limit of the venue. What we now need to do is to fill the schedule with talks / discussions. Please add your suggestions to https://openbsc.osmocom.org/trac/wiki/OsmoDevCon2014 even if it is just a topic you would like to discuss about, and not something that anyone feels compelled to hold a formal presentation about. Looking forward to seeing you in ~ 2 months in Berlin, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From jerlbeck at sysmocom.de Tue Jan 7 14:05:16 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 15:05:16 +0100 Subject: [PATCH] nitb: Set the DST field in generated MM info messages In-Reply-To: <1383915971-21478-1-git-send-email-jerlbeck@sysmocom.de> References: <1383915971-21478-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389103516-23516-1-git-send-email-jerlbeck@sysmocom.de> Currently the NET_DST information element (see GSM 24.008) is not included in generated MM info messages even when the DST field in the timezone info has been set via the VTY or the control interface. This patch modifies gsm48_tx_mm_info() to append this information element if (and only if) a non-zero DST has been configured. The DST IE is not part of GSM 4.8. Therefore it will only be sent, if the DST offset is configured to a value != 0. The DST functionality has been verified with wireshark by Jacob. Sponsored-by: On-Waves ehf --- openbsc/src/libmsc/gsm_04_08.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 997e996..9063f98 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -659,6 +659,7 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) struct tm* gmt_time; struct tm* local_time; int tzunits; + int dst = 0; msg->lchan = conn->lchan; @@ -752,6 +753,9 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) tzunits = tzunits + (bts->tz.mn/15); ptr8[7] = bcdify(tzunits); } + /* Convert DST value */ + if (bts->tz.dst >= 0 && bts->tz.dst <= 2) + dst = bts->tz.dst; } else { /* Need to get GSM offset and convert into 15 min units */ @@ -771,6 +775,17 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) } else ptr8[7] = bcdify(tzunits); + + /* Does not support DST +2 */ + if (local_time->tm_isdst) + dst = 1; + } + + if (dst) { + ptr8 = msgb_put(msg, 3); + ptr8[0] = GSM48_IE_NET_DST; + ptr8[1] = 1; + ptr8[2] = dst; } DEBUGP(DMM, "-> MM INFO\n"); -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 9 13:30:55 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Jan 2014 14:30:55 +0100 Subject: [PATCH 1/4] ipaccess: Enable TCP keepalive by default on all BTS connections In-Reply-To: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> From: Daniel Willmann This way we can find out fast if the connection is broken. Ticket: OW#1060 --- src/input/ipaccess.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 9722b2f..8f9865e 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,10 @@ static void *tall_ipa_ctx; #define TS1_ALLOC_SIZE 900 +#define DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT 30 +#define DEFAULT_TCP_KEEPALIVE_INTERVAL 3 +#define DEFAULT_TCP_KEEPALIVE_RETRY_COUNT 10 + /* * Common propietary IPA messages: * - PONG: in reply to PING. @@ -610,7 +615,7 @@ static int ipaccess_bsc_oml_cb(struct ipa_server_link *link, int fd) { int ret; int idx = 0; - int i; + int i, val; struct e1inp_line *line; struct e1inp_ts *e1i_ts; struct osmo_fd *bfd; @@ -643,6 +648,34 @@ static int ipaccess_bsc_oml_cb(struct ipa_server_link *link, int fd) goto err_line; } + /* Enable TCP keepalive to find out if the connection is gone */ + val = 1; + ret = setsockopt(bfd->fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive: %s\n", + strerror(errno)); + else + LOGP(DLINP, LOGL_NOTICE, "Keepalive is set: %i\n", ret); + +#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) + /* The following options are not portable! */ + val = DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT; + ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive idle time: %s\n", + strerror(errno)); + val = DEFAULT_TCP_KEEPALIVE_INTERVAL; + ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive interval: %s\n", + strerror(errno)); + val = DEFAULT_TCP_KEEPALIVE_RETRY_COUNT; + ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive count: %s\n", + strerror(errno)); +#endif + /* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */ ret = ipaccess_send_id_req(bfd->fd); if (ret < 0) { -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 9 13:30:56 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Jan 2014 14:30:56 +0100 Subject: [PATCH 2/4] ipaccess: Use keep alive for all connections In-Reply-To: <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389274258-14011-2-git-send-email-jerlbeck@sysmocom.de> Keep alive has only been used for OML so far. This patch refactors the socket configuration into an own function and uses it for RSL, too. Ticket: OW#1060 Sponsored-by: On-Waves ehf --- src/input/ipaccess.c | 73 +++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 8f9865e..6b9d93e 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -610,12 +610,54 @@ struct e1inp_driver ipaccess_driver = { .default_delay = 0, }; +static void update_fd_settings(struct e1inp_line *line, int fd) +{ + int ret; + int val; + + if (DEFAULT_TCP_KEEPALIVE_RETRY_COUNT) { + /* Enable TCP keepalive to find out if the connection is gone */ + val = 1; + ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive: %s\n", + strerror(errno)); + else + LOGP(DLINP, LOGL_NOTICE, "Keepalive is set: %i\n", ret); + +#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) + /* The following options are not portable! */ + val = DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT; + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, + &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, + "Failed to set keepalive idle time: %s\n", + strerror(errno)); + val = DEFAULT_TCP_KEEPALIVE_INTERVAL; + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, + &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, + "Failed to set keepalive interval: %s\n", + strerror(errno)); + val = DEFAULT_TCP_KEEPALIVE_RETRY_COUNT; + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, + &val, sizeof(val)); + if (ret < 0) + LOGP(DLINP, LOGL_NOTICE, + "Failed to set keepalive count: %s\n", + strerror(errno)); + } +#endif +} + /* callback of the OML listening filedescriptor */ static int ipaccess_bsc_oml_cb(struct ipa_server_link *link, int fd) { int ret; int idx = 0; - int i, val; + int i; struct e1inp_line *line; struct e1inp_ts *e1i_ts; struct osmo_fd *bfd; @@ -648,33 +690,7 @@ static int ipaccess_bsc_oml_cb(struct ipa_server_link *link, int fd) goto err_line; } - /* Enable TCP keepalive to find out if the connection is gone */ - val = 1; - ret = setsockopt(bfd->fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); - if (ret < 0) - LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive: %s\n", - strerror(errno)); - else - LOGP(DLINP, LOGL_NOTICE, "Keepalive is set: %i\n", ret); - -#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) - /* The following options are not portable! */ - val = DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT; - ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)); - if (ret < 0) - LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive idle time: %s\n", - strerror(errno)); - val = DEFAULT_TCP_KEEPALIVE_INTERVAL; - ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)); - if (ret < 0) - LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive interval: %s\n", - strerror(errno)); - val = DEFAULT_TCP_KEEPALIVE_RETRY_COUNT; - ret = setsockopt(bfd->fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)); - if (ret < 0) - LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive count: %s\n", - strerror(errno)); -#endif + update_fd_settings(line, bfd->fd); /* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */ ret = ipaccess_send_id_req(bfd->fd); @@ -736,6 +752,7 @@ static int ipaccess_bsc_rsl_cb(struct ipa_server_link *link, int fd) strerror(errno)); goto err_socket; } + update_fd_settings(line, bfd->fd); return ret; err_socket: -- 1.7.9.5 From holger at freyther.de Mon Jan 20 07:05:25 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 08:05:25 +0100 Subject: [PATCH 2/4] ipaccess: Use keep alive for all connections In-Reply-To: <1389274258-14011-2-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140120070525.GC27930@xiaoyu.lan> On Thu, Jan 09, 2014 at 02:30:56PM +0100, Jacob Erlbeck wrote: > Keep alive has only been used for OML so far. > > This patch refactors the socket configuration into an own function > and uses it for RSL, too. Good Morning, with the modified 1/4 patch this patch does not apply anymore. Can you please publish your branch so I can merge it today. thanks holger From holger at freyther.de Mon Jan 20 07:09:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 08:09:03 +0100 Subject: [PATCH 2/4] ipaccess: Use keep alive for all connections In-Reply-To: <20140120070525.GC27930@xiaoyu.lan> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-2-git-send-email-jerlbeck@sysmocom.de> <20140120070525.GC27930@xiaoyu.lan> Message-ID: <20140120070903.GD27930@xiaoyu.lan> On Mon, Jan 20, 2014 at 08:05:25AM +0100, Holger Hans Peter Freyther wrote: > On Thu, Jan 09, 2014 at 02:30:56PM +0100, Jacob Erlbeck wrote: > > Keep alive has only been used for OML so far. > > > > This patch refactors the socket configuration into an own function > > and uses it for RSL, too. > > Good Morning, > > with the modified 1/4 patch this patch does not apply anymore. Can you > please publish your branch so I can merge it today. Nevermind. You updated 3/4 so I got the order of the patches wrong. From jerlbeck at sysmocom.de Thu Jan 9 13:30:57 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Jan 2014 14:30:57 +0100 Subject: [PATCH 3/4] input: Make keep alive configurable (generic) In-Reply-To: <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> This patch adds a generic keep alive configuration layer that mainly consists of additional fields in e1_input structs and VTY commands and extensions. Ticket: OW#1060 Sponsored-by: On-Waves ehf --- include/osmocom/abis/e1_input.h | 7 ++++ src/e1_input_vty.c | 69 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 0abf0b8..70df565 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -12,6 +12,7 @@ #include #define NUM_E1_TS 32 +#define E1INP_USE_DEFAULT (-1) enum e1inp_sign_type { E1INP_SIGN_NONE, @@ -134,6 +135,7 @@ struct e1inp_driver { void (*close)(struct e1inp_sign_link *link); void (*vty_show)(struct vty *vty, struct e1inp_line *line); int default_delay; + int has_keepalive; }; struct e1inp_line_ops { @@ -163,6 +165,11 @@ struct e1inp_line { unsigned int port_nr; struct rate_ctr_group *rate_ctr; + /* keepalive configuration */ + int keepalive_idle_timeout; /* 0: disable, secs, or E1INP_USE_DEFAULT */ + int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */ + int keepalive_probe_interval; /* 0: disable, secs, or E1INP_USE_DEFAULT */ + /* array of timestlots */ struct e1inp_ts ts[NUM_E1_TS]; unsigned int num_ts; diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index d99c853..0b4adb2 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -88,6 +88,56 @@ DEFUN(cfg_e1line_port, cfg_e1_line_port_cmd, return CMD_SUCCESS; } +#define KEEPALIVE_HELP "Enable keep-alive probing\n" +static int set_keepalive_params(struct vty *vty, int e1_nr, + int idle, int num_probes, int probe_interval) +{ + struct e1inp_line *line = e1inp_line_find(e1_nr); + + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + if (!line->driver->has_keepalive && num_probes != 0) { + vty_out(vty, "%% Driver '%s' does not support keep alive%s", + line->driver->name, VTY_NEWLINE); + return CMD_WARNING; + } + + line->keepalive_idle_timeout = idle; + line->keepalive_num_probes = num_probes; + line->keepalive_probe_interval = probe_interval; + + return CMD_SUCCESS; +} + +DEFUN(cfg_e1line_keepalive, cfg_e1_line_keepalive_cmd, + "e1_line <0-255> keepalive", + E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), + E1INP_USE_DEFAULT, E1INP_USE_DEFAULT, + E1INP_USE_DEFAULT); +} + +DEFUN(cfg_e1line_keepalive_params, cfg_e1_line_keepalive_params_cmd, + "e1_line <0-255> keepalive <1-300> <1-20> <1-300>", + E1_LINE_HELP KEEPALIVE_HELP + "Idle interval in seconds before probes are sent\n" + "Number of probes to sent\n" + "Delay between probe packets in seconds\n") +{ + return set_keepalive_params(vty, atoi(argv[0]), + atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); +} + +DEFUN(cfg_e1line_no_keepalive, cfg_e1_line_no_keepalive_cmd, + "no e1_line <0-255> keepalive", + NO_STR E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), 0, 0, 0); +} + DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd, "e1_line <0-255> name .LINE", E1_LINE_HELP "Set name for this line\n" "Human readable name\n") @@ -135,6 +185,22 @@ static int e1inp_config_write(struct vty *vty) if (line->name) vty_out(vty, " e1_line %u name %s%s", line->num, line->name, VTY_NEWLINE); + if (!line->keepalive_num_probes) + vty_out(vty, " no e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else if (line->keepalive_idle_timeout == E1INP_USE_DEFAULT && + line->keepalive_num_probes == E1INP_USE_DEFAULT && + line->keepalive_probe_interval == E1INP_USE_DEFAULT) + vty_out(vty, " e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else + vty_out(vty, " e1_line %u keepalive %d %d %d%s", + line->num, + line->keepalive_idle_timeout, + line->keepalive_num_probes, + line->keepalive_probe_interval, + VTY_NEWLINE); + } return CMD_SUCCESS; } @@ -281,6 +347,9 @@ int e1inp_vty_init(void) install_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_name_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd); install_element_ve(&show_e1drv_cmd); install_element_ve(&show_e1line_cmd); -- 1.7.9.5 From holger at freyther.de Mon Jan 13 09:27:07 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 10:27:07 +0100 Subject: [PATCH 3/4] input: Make keep alive configurable (generic) In-Reply-To: <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140113092707.GX9767@xiaoyu.lan> On Thu, Jan 09, 2014 at 02:30:57PM +0100, Jacob Erlbeck wrote: > This patch adds a generic keep alive configuration layer that mainly > consists of additional fields in e1_input structs and VTY commands > and extensions. > enum e1inp_sign_type { > E1INP_SIGN_NONE, > @@ -134,6 +135,7 @@ struct e1inp_driver { > void (*close)(struct e1inp_sign_link *link); > void (*vty_show)(struct vty *vty, struct e1inp_line *line); > int default_delay; > + int has_keepalive; > }; This changes ABI and we should establish a generic way to error when making a new release and forgetting to update the LIBVERSION. I can think of doing: * Modify configure.ac to check the version number and error if a LIBVERSION change is pending. * Use #error in the header file when the XXX version is changed? From holger at freyther.de Thu Jan 16 19:53:14 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 16 Jan 2014 20:53:14 +0100 Subject: [PATCH 3/4] input: Make keep alive configurable (generic) In-Reply-To: <20140113092707.GX9767@xiaoyu.lan> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> <20140113092707.GX9767@xiaoyu.lan> Message-ID: <20140116195314.GV18114@xiaoyu.lan> On Mon, Jan 13, 2014 at 10:27:07AM +0100, Holger Hans Peter Freyther wrote: Hi all, > This changes ABI and we should establish a generic way to error when > making a new release and forgetting to update the LIBVERSION. I can > think of doing: > > * Modify configure.ac to check the version number and error if a > LIBVERSION change is pending. > * Use #error in the header file when the XXX version is changed? the current proposal is to introduce a process that will create a new file in the root of a project where we document the ABI changes. The content of the file will look like this: #library what description / commit summary line From jerlbeck at sysmocom.de Fri Jan 17 09:30:51 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 17 Jan 2014 10:30:51 +0100 Subject: [PATCH 3/4] input: Make keep alive configurable (generic) In-Reply-To: <20140116195314.GV18114@xiaoyu.lan> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> <20140113092707.GX9767@xiaoyu.lan> <20140116195314.GV18114@xiaoyu.lan> Message-ID: <52D8F84B.1030206@sysmocom.de> On 16.01.2014 20:53, Holger Hans Peter Freyther wrote: > On Mon, Jan 13, 2014 at 10:27:07AM +0100, Holger Hans Peter Freyther wrote: > > Hi all, > > > the current proposal is to introduce a process that will create a > new file in the root of a project where we document the ABI changes. > The content of the file will look like this: > > #library what description / commit summary line > > More precisely, the idea was to have a TODO-RELEASE file in the project's top directory containing a single line per 'what' and commit which is part of the commit itself. When this file is empty (except for empty lines and comment lines starting with a '#'), a release can be finished. 'what' is one of the following strings (more to come): 'abi-change' the ABI (structs, function parameters) has changed e.g. due to modifications or removals. When there is at least one such line, the LIBVERSION 'age' field must be reset and the 'current' field must be incremented when doing a release. All lines marked with 'abi-change' or 'abi-add' can be removed then. 'abi-add' a function or struct has been added but the ABI has not changed otherwise (so it remains compatible). When there is at least one such line (and no 'abi-change' line'), the LIBVERSION 'age' and 'current' fields must be incremented when doing a release. All such lines can be removed then. The 'abi-add' variant is probably less important but I've included it nevertheless for completeness. Jacob From holger at freyther.de Mon Jan 13 09:35:29 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 10:35:29 +0100 Subject: [PATCH 3/4] input: Make keep alive configurable (generic) In-Reply-To: <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140113093529.GY9767@xiaoyu.lan> On Thu, Jan 09, 2014 at 02:30:57PM +0100, Jacob Erlbeck wrote: > + /* keepalive configuration */ > + int keepalive_idle_timeout; /* 0: disable, secs, or E1INP_USE_DEFAULT */ > + int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */ > + int keepalive_probe_interval; /* 0: disable, secs, or E1INP_USE_DEFAULT */ "disable" is not fully accurate. keepalive_num_probes is used in the ipaccess.c and the normal code to check if the keepalive handling is enabled? Do you want to update the comments? From jerlbeck at sysmocom.de Thu Jan 16 16:57:37 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 16 Jan 2014 17:57:37 +0100 Subject: [PATCH] input: Make keep alive configurable (generic) In-Reply-To: <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> References: <1389274258-14011-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389891457-19680-1-git-send-email-jerlbeck@sysmocom.de> This patch adds a generic keep alive configuration layer that mainly consists of additional fields in e1_input structs and VTY commands and extensions. Ticket: OW#1060 Sponsored-by: On-Waves ehf --- TODO-RELEASE | 2 ++ include/osmocom/abis/e1_input.h | 7 ++++ src/e1_input_vty.c | 69 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 TODO-RELEASE diff --git a/TODO-RELEASE b/TODO-RELEASE new file mode 100644 index 0000000..98b9a64 --- /dev/null +++ b/TODO-RELEASE @@ -0,0 +1,2 @@ +#library what description / commit summary line +libosmoabis abi-change input: Make keep alive configurable (generic) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 0abf0b8..70df565 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -12,6 +12,7 @@ #include #define NUM_E1_TS 32 +#define E1INP_USE_DEFAULT (-1) enum e1inp_sign_type { E1INP_SIGN_NONE, @@ -134,6 +135,7 @@ struct e1inp_driver { void (*close)(struct e1inp_sign_link *link); void (*vty_show)(struct vty *vty, struct e1inp_line *line); int default_delay; + int has_keepalive; }; struct e1inp_line_ops { @@ -163,6 +165,11 @@ struct e1inp_line { unsigned int port_nr; struct rate_ctr_group *rate_ctr; + /* keepalive configuration */ + int keepalive_idle_timeout; /* 0: disable, secs, or E1INP_USE_DEFAULT */ + int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */ + int keepalive_probe_interval; /* 0: disable, secs, or E1INP_USE_DEFAULT */ + /* array of timestlots */ struct e1inp_ts ts[NUM_E1_TS]; unsigned int num_ts; diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index d99c853..0b4adb2 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -88,6 +88,56 @@ DEFUN(cfg_e1line_port, cfg_e1_line_port_cmd, return CMD_SUCCESS; } +#define KEEPALIVE_HELP "Enable keep-alive probing\n" +static int set_keepalive_params(struct vty *vty, int e1_nr, + int idle, int num_probes, int probe_interval) +{ + struct e1inp_line *line = e1inp_line_find(e1_nr); + + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + if (!line->driver->has_keepalive && num_probes != 0) { + vty_out(vty, "%% Driver '%s' does not support keep alive%s", + line->driver->name, VTY_NEWLINE); + return CMD_WARNING; + } + + line->keepalive_idle_timeout = idle; + line->keepalive_num_probes = num_probes; + line->keepalive_probe_interval = probe_interval; + + return CMD_SUCCESS; +} + +DEFUN(cfg_e1line_keepalive, cfg_e1_line_keepalive_cmd, + "e1_line <0-255> keepalive", + E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), + E1INP_USE_DEFAULT, E1INP_USE_DEFAULT, + E1INP_USE_DEFAULT); +} + +DEFUN(cfg_e1line_keepalive_params, cfg_e1_line_keepalive_params_cmd, + "e1_line <0-255> keepalive <1-300> <1-20> <1-300>", + E1_LINE_HELP KEEPALIVE_HELP + "Idle interval in seconds before probes are sent\n" + "Number of probes to sent\n" + "Delay between probe packets in seconds\n") +{ + return set_keepalive_params(vty, atoi(argv[0]), + atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); +} + +DEFUN(cfg_e1line_no_keepalive, cfg_e1_line_no_keepalive_cmd, + "no e1_line <0-255> keepalive", + NO_STR E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), 0, 0, 0); +} + DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd, "e1_line <0-255> name .LINE", E1_LINE_HELP "Set name for this line\n" "Human readable name\n") @@ -135,6 +185,22 @@ static int e1inp_config_write(struct vty *vty) if (line->name) vty_out(vty, " e1_line %u name %s%s", line->num, line->name, VTY_NEWLINE); + if (!line->keepalive_num_probes) + vty_out(vty, " no e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else if (line->keepalive_idle_timeout == E1INP_USE_DEFAULT && + line->keepalive_num_probes == E1INP_USE_DEFAULT && + line->keepalive_probe_interval == E1INP_USE_DEFAULT) + vty_out(vty, " e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else + vty_out(vty, " e1_line %u keepalive %d %d %d%s", + line->num, + line->keepalive_idle_timeout, + line->keepalive_num_probes, + line->keepalive_probe_interval, + VTY_NEWLINE); + } return CMD_SUCCESS; } @@ -281,6 +347,9 @@ int e1inp_vty_init(void) install_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_name_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd); install_element_ve(&show_e1drv_cmd); install_element_ve(&show_e1line_cmd); -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 16 17:10:37 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 16 Jan 2014 18:10:37 +0100 Subject: [PATCH] input: Make keep alive configurable (generic) In-Reply-To: <1389891457-19680-1-git-send-email-jerlbeck@sysmocom.de> References: <1389891457-19680-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389892238-20120-1-git-send-email-jerlbeck@sysmocom.de> This patch adds a generic keep alive configuration layer that mainly consists of additional fields in e1_input structs and VTY commands and extensions. Ticket: OW#1060 Sponsored-by: On-Waves ehf --- TODO-RELEASE | 2 ++ include/osmocom/abis/e1_input.h | 7 ++++ src/e1_input_vty.c | 69 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 TODO-RELEASE diff --git a/TODO-RELEASE b/TODO-RELEASE new file mode 100644 index 0000000..98b9a64 --- /dev/null +++ b/TODO-RELEASE @@ -0,0 +1,2 @@ +#library what description / commit summary line +libosmoabis abi-change input: Make keep alive configurable (generic) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 0abf0b8..9b77893 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -12,6 +12,7 @@ #include #define NUM_E1_TS 32 +#define E1INP_USE_DEFAULT (-1) enum e1inp_sign_type { E1INP_SIGN_NONE, @@ -134,6 +135,7 @@ struct e1inp_driver { void (*close)(struct e1inp_sign_link *link); void (*vty_show)(struct vty *vty, struct e1inp_line *line); int default_delay; + int has_keepalive; }; struct e1inp_line_ops { @@ -163,6 +165,11 @@ struct e1inp_line { unsigned int port_nr; struct rate_ctr_group *rate_ctr; + /* keepalive configuration */ + int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */ + int keepalive_idle_timeout; /* secs, or E1INP_USE_DEFAULT */ + int keepalive_probe_interval; /* secs or E1INP_USE_DEFAULT */ + /* array of timestlots */ struct e1inp_ts ts[NUM_E1_TS]; unsigned int num_ts; diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index d99c853..0b4adb2 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -88,6 +88,56 @@ DEFUN(cfg_e1line_port, cfg_e1_line_port_cmd, return CMD_SUCCESS; } +#define KEEPALIVE_HELP "Enable keep-alive probing\n" +static int set_keepalive_params(struct vty *vty, int e1_nr, + int idle, int num_probes, int probe_interval) +{ + struct e1inp_line *line = e1inp_line_find(e1_nr); + + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + if (!line->driver->has_keepalive && num_probes != 0) { + vty_out(vty, "%% Driver '%s' does not support keep alive%s", + line->driver->name, VTY_NEWLINE); + return CMD_WARNING; + } + + line->keepalive_idle_timeout = idle; + line->keepalive_num_probes = num_probes; + line->keepalive_probe_interval = probe_interval; + + return CMD_SUCCESS; +} + +DEFUN(cfg_e1line_keepalive, cfg_e1_line_keepalive_cmd, + "e1_line <0-255> keepalive", + E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), + E1INP_USE_DEFAULT, E1INP_USE_DEFAULT, + E1INP_USE_DEFAULT); +} + +DEFUN(cfg_e1line_keepalive_params, cfg_e1_line_keepalive_params_cmd, + "e1_line <0-255> keepalive <1-300> <1-20> <1-300>", + E1_LINE_HELP KEEPALIVE_HELP + "Idle interval in seconds before probes are sent\n" + "Number of probes to sent\n" + "Delay between probe packets in seconds\n") +{ + return set_keepalive_params(vty, atoi(argv[0]), + atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); +} + +DEFUN(cfg_e1line_no_keepalive, cfg_e1_line_no_keepalive_cmd, + "no e1_line <0-255> keepalive", + NO_STR E1_LINE_HELP KEEPALIVE_HELP) +{ + return set_keepalive_params(vty, atoi(argv[0]), 0, 0, 0); +} + DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd, "e1_line <0-255> name .LINE", E1_LINE_HELP "Set name for this line\n" "Human readable name\n") @@ -135,6 +185,22 @@ static int e1inp_config_write(struct vty *vty) if (line->name) vty_out(vty, " e1_line %u name %s%s", line->num, line->name, VTY_NEWLINE); + if (!line->keepalive_num_probes) + vty_out(vty, " no e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else if (line->keepalive_idle_timeout == E1INP_USE_DEFAULT && + line->keepalive_num_probes == E1INP_USE_DEFAULT && + line->keepalive_probe_interval == E1INP_USE_DEFAULT) + vty_out(vty, " e1_line %u keepalive%s", line->num, + VTY_NEWLINE); + else + vty_out(vty, " e1_line %u keepalive %d %d %d%s", + line->num, + line->keepalive_idle_timeout, + line->keepalive_num_probes, + line->keepalive_probe_interval, + VTY_NEWLINE); + } return CMD_SUCCESS; } @@ -281,6 +347,9 @@ int e1inp_vty_init(void) install_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_name_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd); install_element_ve(&show_e1drv_cmd); install_element_ve(&show_e1line_cmd); -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 9 13:30:58 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Jan 2014 14:30:58 +0100 Subject: [PATCH 4/4] ipaccess: Make TCP keep-alive configurable In-Reply-To: <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389274258-14011-4-git-send-email-jerlbeck@sysmocom.de> This patch changes the implementation to use the keep-alive configuration fields instead of constants. Ticket: OW#1060 Sponsored-by: On-Waves ehf --- src/input/ipaccess.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 6b9d93e..4684520 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -608,6 +608,7 @@ struct e1inp_driver ipaccess_driver = { .line_update = ipaccess_line_update, .close = ipaccess_close, .default_delay = 0, + .has_keepalive = 1, }; static void update_fd_settings(struct e1inp_line *line, int fd) @@ -615,7 +616,7 @@ static void update_fd_settings(struct e1inp_line *line, int fd) int ret; int val; - if (DEFAULT_TCP_KEEPALIVE_RETRY_COUNT) { + if (line->keepalive_num_probes) { /* Enable TCP keepalive to find out if the connection is gone */ val = 1; ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); @@ -627,21 +628,27 @@ static void update_fd_settings(struct e1inp_line *line, int fd) #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) /* The following options are not portable! */ - val = DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT; + val = line->keepalive_idle_timeout > 0 ? + line->keepalive_idle_timeout : + DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT; ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)); if (ret < 0) LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive idle time: %s\n", strerror(errno)); - val = DEFAULT_TCP_KEEPALIVE_INTERVAL; + val = line->keepalive_probe_interval > -1 ? + line->keepalive_probe_interval : + DEFAULT_TCP_KEEPALIVE_INTERVAL; ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)); if (ret < 0) LOGP(DLINP, LOGL_NOTICE, "Failed to set keepalive interval: %s\n", strerror(errno)); - val = DEFAULT_TCP_KEEPALIVE_RETRY_COUNT; + val = line->keepalive_num_probes > 0 ? + line->keepalive_num_probes : + DEFAULT_TCP_KEEPALIVE_RETRY_COUNT; ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)); if (ret < 0) -- 1.7.9.5 From holger at freyther.de Mon Jan 13 09:04:47 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 10:04:47 +0100 Subject: [PATCH 1/4] ipaccess: Enable TCP keepalive by default on all BTS connections In-Reply-To: <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140113090447.GW9767@xiaoyu.lan> On Thu, Jan 09, 2014 at 02:30:55PM +0100, Jacob Erlbeck wrote: > From: Daniel Willmann > > This way we can find out fast if the connection is broken. s/fast/quickly? From jerlbeck at sysmocom.de Tue Jan 14 08:30:26 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 09:30:26 +0100 Subject: [PATCH 1/4] ipaccess: Enable TCP keepalive by default on all BTS connections In-Reply-To: <20140113090447.GW9767@xiaoyu.lan> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <20140113090447.GW9767@xiaoyu.lan> Message-ID: <52D4F5A2.7000906@sysmocom.de> On 13.01.2014 10:04, Holger Hans Peter Freyther wrote: > On Thu, Jan 09, 2014 at 02:30:55PM +0100, Jacob Erlbeck wrote: >> From: Daniel Willmann >> >> This way we can find out fast if the connection is broken. > > s/fast/quickly? > 'fast' is an adverb, too. So I guess it should be okay syntactically. But I'd rather go for the comparative and use 'faster' (or 'more quickly'). Jacob From daniel at totalueberwachung.de Tue Jan 14 08:50:53 2014 From: daniel at totalueberwachung.de (Daniel Willmann) Date: Tue, 14 Jan 2014 09:50:53 +0100 Subject: [PATCH 1/4] ipaccess: Enable TCP keepalive by default on all BTS connections In-Reply-To: <52D4F5A2.7000906@sysmocom.de> References: <1385381563-28967-1-git-send-email-jerlbeck@sysmocom.de> <1389274258-14011-1-git-send-email-jerlbeck@sysmocom.de> <20140113090447.GW9767@xiaoyu.lan> <52D4F5A2.7000906@sysmocom.de> Message-ID: <20140114085053.GD23205@adrastea.totalueberwachung.de> On Tue, 2014-01-14 at 09:30, Jacob Erlbeck wrote: > On 13.01.2014 10:04, Holger Hans Peter Freyther wrote: > > On Thu, Jan 09, 2014 at 02:30:55PM +0100, Jacob Erlbeck wrote: > >> From: Daniel Willmann > >> > >> This way we can find out fast if the connection is broken. > > > > s/fast/quickly? > > > > 'fast' is an adverb, too. So I guess it should be okay syntactically. > But I'd rather go for the comparative and use 'faster' (or 'more quickly'). Reading it here I think I'd prefer (more) quickly. In any case I think it's a minor cosmetical change and either of the possibilities would work. Regards, Daniel From holger at freyther.de Wed Jan 8 09:40:21 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 8 Jan 2014 10:40:21 +0100 Subject: [PATCH 3/4] Fix: Nokia BTS does not send RELease CONFirm message for local end release In-Reply-To: <52B2E948.3080007@eversberg.eu> References: <1386255759-8600-1-git-send-email-jolly@eversberg.eu> <1386255759-8600-3-git-send-email-jolly@eversberg.eu> <20131206074834.GA31478@xiaoyu.lan> <52A1A141.7020403@eversberg.eu> <20131206131559.GB24984@xiaoyu.lan> <20131219102747.GD30292@xiaoyu.lan> <52B2E948.3080007@eversberg.eu> Message-ID: <20140108094021.GB29279@xiaoyu.lan> On Thu, Dec 19, 2013 at 01:40:40PM +0100, Andreas Eversberg wrote: > note that this patch is just a preview. it works but has only been > tested briefly. Shall we apply this patch? From andreas at eversberg.eu Wed Jan 8 11:47:12 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 08 Jan 2014 12:47:12 +0100 Subject: [PATCH 3/4] Fix: Nokia BTS does not send RELease CONFirm message for local end release In-Reply-To: <20140108094021.GB29279@xiaoyu.lan> References: <1386255759-8600-1-git-send-email-jolly@eversberg.eu> <1386255759-8600-3-git-send-email-jolly@eversberg.eu> <20131206074834.GA31478@xiaoyu.lan> <52A1A141.7020403@eversberg.eu> <20131206131559.GB24984@xiaoyu.lan> <20131219102747.GD30292@xiaoyu.lan> <52B2E948.3080007@eversberg.eu> <20140108094021.GB29279@xiaoyu.lan> Message-ID: <52CD3AC0.8070305@eversberg.eu> Holger Hans Peter Freyther wrote: > On Thu, Dec 19, 2013 at 01:40:40PM +0100, Andreas Eversberg wrote: > >> note that this patch is just a preview. it works but has only been >> tested briefly. >> > Shall we apply this patch? > dear holger, after several handover tests, i can confirm that this patch works. please use the recently rebased and distchecked version: a83f36b24d3a6bcec3cd70b3cb70a21e7fc8571a regards, andreas From holger at freyther.de Thu Jan 9 07:19:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 9 Jan 2014 08:19:03 +0100 Subject: [PATCH 3/4] Fix: Nokia BTS does not send RELease CONFirm message for local end release In-Reply-To: <52CD3AC0.8070305@eversberg.eu> References: <1386255759-8600-1-git-send-email-jolly@eversberg.eu> <1386255759-8600-3-git-send-email-jolly@eversberg.eu> <20131206074834.GA31478@xiaoyu.lan> <52A1A141.7020403@eversberg.eu> <20131206131559.GB24984@xiaoyu.lan> <20131219102747.GD30292@xiaoyu.lan> <52B2E948.3080007@eversberg.eu> <20140108094021.GB29279@xiaoyu.lan> <52CD3AC0.8070305@eversberg.eu> Message-ID: <20140109071903.GD3546@xiaoyu.lan> On Wed, Jan 08, 2014 at 12:47:12PM +0100, Andreas Eversberg wrote: Good Morning, > after several handover tests, i can confirm that this patch works. > please use the recently rebased and distchecked version: > a83f36b24d3a6bcec3cd70b3cb70a21e7fc8571a I have pushed this change. IIRC the local release also applies to SAPI==3 as well. So the workaround should already trigger when SMS is being sent. holger > From andreas at eversberg.eu Tue Jan 7 11:05:53 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 07 Jan 2014 12:05:53 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <20131219100901.GC30292@xiaoyu.lan> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> Message-ID: <52CBDF91.9010505@eversberg.eu> Holger Hans Peter Freyther wrote: > What about this? It makes it mandatory to define fr first. The other > things I noticed is: > > * Currently the default codec MNCC-intern uses is EFR. After the change > it will be FR. > * The BTS should be involved as well to ack/nack the codec support > (we can do that later) > * The BSC part should start to honor this support too. > > dear holger, i updated/rebased and tested the patch. i changed the default codec for built-in MNCC call control to FR. in later patches this setting for default codec becomes obsolete, because codec selection (negotiation) is then done by exermining capabilities/preferences of the calling and the called phone and the codec-support of their BTSes. what do you mean by "The BSC part should start to honor this support too."? regards, andreas -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: codec_support.patch URL: From holger at freyther.de Thu Jan 9 07:29:54 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 9 Jan 2014 08:29:54 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52CBDF91.9010505@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> Message-ID: <20140109072954.GF3546@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:05:53PM +0100, Andreas Eversberg wrote: > what do you mean by "The BSC part should start to honor this support too."? Codec selection in a real network works a bit differently. It is applied in the BSC and the MSC. The MSC can/will look at the bearer capabilities and then ask the BSC to choose from a list of codecs. In the future bssmap_handle_assignm_req should start to use the new list instead of the "codec-list" from the "msc" section. And in the long run NITB should do what a MSC does and select candidates and the BSC-API should then select from this list based on the capabilities of the hardware. holger From andreas at eversberg.eu Thu Jan 9 10:13:11 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 09 Jan 2014 11:13:11 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <20140109072954.GF3546@xiaoyu.lan> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140109072954.GF3546@xiaoyu.lan> Message-ID: <52CE7637.2080108@eversberg.eu> Holger Hans Peter Freyther wrote: > Codec selection in a real network works a bit differently. It is applied > in the BSC and the MSC. The MSC can/will look at the bearer capabilities > and then ask the BSC to choose from a list of codecs. > in oder to select a codec, the MSC must know. - what codecs it supports (or the other end, in case of TFO) - what codecs the MS supports (bearer capabilities) - what codecs the BTS supports in my testing branch: the negotiation is done with LCR and even with built-in MNCC support of osmo-nitb. in case of built-in MNCC, a commonly supported codec (by both MS in a call) is used. i do not know how the MSC (in a real network) knows about what codecs are supported by the BTS in order to select a supported codec. in this patch i simply remove unsupported codecs from bearer capabilities, so all remaining codecs are supported by BTS and the MS. the MSC will only receive a list of commonly supported codecs. my question is: how does the MSC in a real network knows what codecs are supported by BTS, so it can skip unsupported codecs when negotiating with the other end? From rp.labs at gmx.ch Mon Jan 13 00:34:26 2014 From: rp.labs at gmx.ch (Labs) Date: Mon, 13 Jan 2014 01:34:26 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52CE7637.2080108@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140109072954.GF3546@xiaoyu.lan> <52CE7637.2080108@eversberg.eu> Message-ID: <52D33492.4060409@gmx.ch> Hello, On 01/09/2014 11:13 AM, Andreas Eversberg wrote: > my question is: how does the MSC in a real network knows what codecs are > supported by BTS, so it can skip unsupported codecs when negotiating > with the other end? > My understanding is that the BTS is not involved at all in this negotiation. Only MS, BSC and MSC. BTS just passes the messages between MS and BSC. In the initial call setup procedure the MS is sending to MSC the supported codecs list. Information is sent in an L3 DTAP message through BSC but BSC is not involved this time. MSC is building after that a list of supported codecs by both ends and is sending the list to the BSC. If the codec chosen by BSC is supported by both ends than you have a transcoder free operation. All elements involved needs to support TrFO to work. More in 23.153 and 45.009. In case of A over TDM you can not have TrFO working, just for A over IP. I looked over the code (I'm not a programmer) and I cannot see where you specify the bit rate for AMR codec. In 45.009 3.4.3 you can check the rules for initial codec mode and cases when the bit rate can change. In real networks I saw most of the time AMR used and I also saw same BSCs overwriting the ICM by selecting the highest bitrate when message is sent through Abis interface to MS. Normal behavior is to follow the rules in 3.4.3. In TrFO the bitrate will not be signalled by MSC in L3 messages (this function is not even implemented from what I saw) because there are cases when MSC is not involved like intra-BSC handover with a local MS. I hope I wrote everything correctly. Regards, R. From holger at freyther.de Thu Jan 9 07:30:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 9 Jan 2014 08:30:38 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52CBDF91.9010505@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> Message-ID: <20140109073038.GG3546@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:05:53PM +0100, Andreas Eversberg wrote: > +static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[]) and I was too quick. "_" symbols are reserved for the system GCC/GLIBC. Right now this should not be a problem though. From holger at freyther.de Thu Jan 9 17:53:49 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 9 Jan 2014 18:53:49 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52CBDF91.9010505@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> Message-ID: <20140109175349.GA11093@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:05:53PM +0100, Andreas Eversberg wrote: > commit 037c6084ab68785666a84c89a5f5d45de6a44620 hi, git am fails on the patch. Can you run git format-patch again and send the patch? holger From holger at freyther.de Wed Jan 15 15:08:43 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 15 Jan 2014 16:08:43 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52CBDF91.9010505@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> Message-ID: <20140115150843.GA27829@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:05:53PM +0100, Andreas Eversberg wrote: > Each BTS can be configured for speech support (other than GSM full rate) > > Speech codings which are not supported by BTS will be removed from the > bearer capability information element after parsing. This way it is not > required for the MNCC application to consider support of each BTS. > > Only GSM full rate is supported by default. coverity complains about two issues. Make sure to put "Fixes: Coverity CID .." into the commit message. ** CID 1155311: Dereference after null check (FORWARD_NULL) /src/libmsc/gsm_04_08.c: 1825 in gsm48_cc_rx_setup() ** CID 1155312: Dereference after null check (FORWARD_NULL) /src/libmsc/gsm_04_08.c: 1979 in gsm48_cc_rx_call_conf() _______________________________________________________________________________________________ +_________ *** CID 1155311: Dereference after null check (FORWARD_NULL) /src/libmsc/gsm_04_08.c: 1825 in gsm48_cc_rx_setup() 1819 1820 /* bearer capability */ 1821 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { 1822 setup.fields |= MNCC_F_BEARER_CAP; 1823 gsm48_decode_bearer_cap(&setup.bearer_cap, 1824 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); >>> CID 1155311: Dereference after null check (FORWARD_NULL) >>> Dereferencing null pointer "trans->conn". 1825 apply_codec_restrictions(trans->conn->bts, &setup.bearer_cap); 1826 } 1827 /* facility */ 1828 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { 1829 setup.fields |= MNCC_F_FACILITY; 1830 gsm48_decode_facility(&setup.facility, *** CID 1155312: Dereference after null check (FORWARD_NULL) /src/libmsc/gsm_04_08.c: 1979 in gsm48_cc_rx_call_conf() 1973 #endif 1974 /* bearer capability */ 1975 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { 1976 call_conf.fields |= MNCC_F_BEARER_CAP; 1977 gsm48_decode_bearer_cap(&call_conf.bearer_cap, 1978 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); >>> CID 1155312: Dereference after null check (FORWARD_NULL) >>> Dereferencing null pointer "trans->conn". 1979 apply_codec_restrictions(trans->conn->bts, &call_conf.bearer_cap); 1980 } 1981 /* cause */ 1982 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { 1983 call_conf.fields |= MNCC_F_CAUSE; 1984 gsm48_decode_cause(&call_conf.cause, From andreas at eversberg.eu Wed Jan 15 15:23:23 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 15 Jan 2014 16:23:23 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <20140115150843.GA27829@xiaoyu.lan> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140115150843.GA27829@xiaoyu.lan> Message-ID: <52D6A7EB.2000306@eversberg.eu> Holger Hans Peter Freyther wrote: > ** CID 1155311: Dereference after null check (FORWARD_NULL) > /src/libmsc/gsm_04_08.c: 1825 in gsm48_cc_rx_setup() > > ** CID 1155312: Dereference after null check (FORWARD_NULL) > /src/libmsc/gsm_04_08.c: 1979 in gsm48_cc_rx_call_conf() hi holger, in both functions is a check for conn and lchan not beeing NULL: if (trans->conn && trans->conn->lchan) setup.lchan_type = trans->conn->lchan->type; the functions are called by gsm0408_rcv_cc(). from there i can see that trans->conn->lchan is always set, so the if-condition above is not required. regards, andreas From holger at freyther.de Wed Jan 15 16:33:42 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 15 Jan 2014 17:33:42 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52D6A7EB.2000306@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140115150843.GA27829@xiaoyu.lan> <52D6A7EB.2000306@eversberg.eu> Message-ID: <20140115163342.GC18114@xiaoyu.lan> On Wed, Jan 15, 2014 at 04:23:23PM +0100, Andreas Eversberg wrote: > in both functions is a check for conn and lchan not beeing NULL: > > if (trans->conn && trans->conn->lchan) > setup.lchan_type = trans->conn->lchan->type; > > the functions are called by gsm0408_rcv_cc(). from there i can see that > trans->conn->lchan is always set, so the if-condition above is not required. > Exactly. Coverity points out that first you check if (trans->conn), there is no return and later we _unconditionally_ do "trans->conn->bts". a.) Coverity is right and there are conditions it can crash b.) The if (trans->conn) is not needed. Could you please elaborate which of the two is the case here? holger From andreas at eversberg.eu Wed Jan 15 17:10:06 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 15 Jan 2014 18:10:06 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <20140115163342.GC18114@xiaoyu.lan> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140115150843.GA27829@xiaoyu.lan> <52D6A7EB.2000306@eversberg.eu> <20140115163342.GC18114@xiaoyu.lan> Message-ID: <52D6C0EE.6040400@eversberg.eu> Holger Hans Peter Freyther wrote: > b.) The if (trans->conn) is not needed. this is the case. From holger at freyther.de Wed Jan 15 18:21:41 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 15 Jan 2014 19:21:41 +0100 Subject: [PATCH 1/4] Each BTS can be configured for speech support (other than GSM full rate) In-Reply-To: <52D6C0EE.6040400@eversberg.eu> References: <1386437548-2280-1-git-send-email-jolly@eversberg.eu> <20131218152125.GB13933@xiaoyu.lan> <52B1CA8C.2040802@eversberg.eu> <20131219100901.GC30292@xiaoyu.lan> <52CBDF91.9010505@eversberg.eu> <20140115150843.GA27829@xiaoyu.lan> <52D6A7EB.2000306@eversberg.eu> <20140115163342.GC18114@xiaoyu.lan> <52D6C0EE.6040400@eversberg.eu> Message-ID: <20140115182141.GI18114@xiaoyu.lan> On Wed, Jan 15, 2014 at 06:10:06PM +0100, Andreas Eversberg wrote: > Holger Hans Peter Freyther wrote: > >b.) The if (trans->conn) is not needed. > this is the case. and why is that? Who calls the method and are the callers already doing the null check? Please create a patch and mention the CIDs in the commit message. From laforge at gnumonks.org Sun Jan 12 18:18:35 2014 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 12 Jan 2014 19:18:35 +0100 Subject: abis_nm_pchan4chcomb API and return value In-Reply-To: <20131212164551.GA21967@xiaoyu.lan> References: <20131212164551.GA21967@xiaoyu.lan> Message-ID: <20140112181835.GQ23594@nataraja> Hi Holger, sorry for the late response. On Thu, Dec 12, 2013 at 05:45:51PM +0100, Holger Hans Peter Freyther wrote: > enum abis_nm_chan_comb abis_nm_pchan4chcomb(uint8_t chcomb) > > From the name of the method I would expect it to return a pchan. E.g. > it should return gsm_phys_chan_config? yes, correct. > static const enum abis_nm_chan_comb chcomb4pchan[] = { > > and at the indexes we use values from gsm_phys_chan_config. Do you think > the below is correct? yes, the patch is correct. I noticed you applied it already... Regards, -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From andreas at eversberg.eu Sat Jan 4 09:01:15 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 04 Jan 2014 10:01:15 +0100 Subject: Making jolly/testing ready to be merged? In-Reply-To: <20131227145903.GA20567@xiaoyu.lan> References: <20131227145903.GA20567@xiaoyu.lan> Message-ID: <52C7CDDB.9020309@eversberg.eu> Holger Hans Peter Freyther wrote: > I wanted to start with merging the Connection Failure Criteria code but > I am confused about the conversion. When parsing the criteria value from > from the VTY you divide by four and subtract (so 4 becomes 0). You ondo > this when saving the config and patching it in the nanoBTS attribute > array. > > Wouldn't it be more easy to not doing the conversion? > dear holger, the attribute "bts->si_common.cell_options.radio_link_timeout" is defined in gsm_04_08.h of libosmocore: struct gsm48_cell_options { uint8_t radio_link_timeout:4, dtx:2, pwrc:1, spare:1; } __attribute__ ((packed)); we need this conversion, since we also need "cell_options" for SI3 and SI6. i just use this attribute (and convert it back), so i don't need to add an extra attribute to "bts" structure. regards, andreas From holger at freyther.de Sat Jan 4 10:26:00 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 4 Jan 2014 11:26:00 +0100 Subject: Making jolly/testing ready to be merged? In-Reply-To: <52C7CDDB.9020309@eversberg.eu> References: <20131227145903.GA20567@xiaoyu.lan> <52C7CDDB.9020309@eversberg.eu> Message-ID: <20140104102600.GD21308@xiaoyu.lan> On Sat, Jan 04, 2014 at 10:01:15AM +0100, Andreas Eversberg wrote: Andreas, > we need this conversion, since we also need "cell_options" for SI3 and > SI6. i just use this attribute (and convert it back), so i don't need to > add an extra attribute to "bts" structure. Okay, I would prefer macros/inline functions that convert from the numerical value to the on-wire representation. It is a complain I have with the PCU code and here as well. Here it might look like overkill. In terms of Software Engineering it is all about information hiding to reduce the complexity. One way to do this is to think about what secrets a method/block/component/module has/should have. E.g. in the nanoBTS patch method it knows about how to patch the tables we have but it should not necessarily know about the different forms of representation of the radio link timeout. Or in the more general note. Not all parts of the code should know everything. - bts->si_common.cell_options.radio_link_timeout = 7; /* 12 */ + bts->si_common.cell_options.radio_link_timeout = 7; /* Use RADIO LINK TIMEOUT of 32 */ + vty_out(vty, " radio-link-timeout %d%s", + (bts->si_common.cell_options.radio_link_timeout + 1) << 2, + VTY_NEWLINE); + bts->si_common.cell_options.radio_link_timeout = (atoi(argv[0])>>2) - 1; + /* patch CON_FAIL_CRIT */ + nanobts_attr_bts[13] = + (bts->si_common.cell_options.radio_link_timeout + 1) << 2; + E.g. you could do something like this in OpenBSC static inline int get_radio_link_timeout(struct gsm_bts *bts) { return (bts->si_common.cell_options.radio_link_timeout + 1) << 2 } static inline void set_radio_link_timeout(struct gsm_bts *bts, int value) { bts->si_common.cell_options.radio_link_timeout = (value>>2) - 1; } and the above code would become.. + set_radio_link_timeout(bts, 32); + vty_out(vty, " radio-link-timeout %d%s", + get_radio_link_timeout(bts), VTY_NEWLINE); + nanobts_attr_bts[13] = get_radio_link_timeout(bts); it is shorter, more expressive, comes at no code increase (in striped binaries), hides the secret of the conversion in a single place, etc. holger From holger at freyther.de Wed Jan 1 18:36:14 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 1 Jan 2014 19:36:14 +0100 Subject: RFC adding another debug log statement In-Reply-To: <52C232A4.4030100@fiane.dyndns.org> References: <20131230095534.GE22160@xiaoyu.lan> <52C232A4.4030100@fiane.dyndns.org> Message-ID: <20140101183614.GA21712@xiaoyu.lan> On Tue, Dec 31, 2013 at 03:57:40AM +0100, noselasd at fiane.dyndns.org wrote: > see attached patch for an example > (it may now truncate the hex dumps at a byte boundary vs at a nibble > when using snprintf if the hex exceeds sizeof(hexd_buff) though) nice speed-up in deed. I will add a regression for the new truncation. We seldomly (read never) deal with messages of 4k. The below code goes from: real 0m3.233s user 0m3.212s sys 0m0.000s to: real 0m0.085s user 0m0.084s sys 0m0.000s #include #include #include int main(int argc, char **argv) { static const int lengths[] = { 23, 1000, 52 }; char buf[4096]; int i; for (i = 0; i < 30000; ++i) { char *res = osmo_hexdump(buf, lengths[i & 3]); } } From holger at freyther.de Thu Jan 2 19:35:54 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 2 Jan 2014 20:35:54 +0100 Subject: RFC fix last coverity report with SI handling in osmo-bts Message-ID: <20140102193554.GB8055@xiaoyu.lan> Hi, the coverity tools points out that it might be possible to access the si.buf atfer _MAX_SYSINFO_TYPE and before < 32. Looking at the code I also notice that: osmo_rsl2sitype takes an uint8_t but makes no range checking, same goes for osmo_sitype2rsl. I plan to apply the below patch for osmo-bts. This would resolve the last open Coverity report for osmo-bts. It would be nice if we could add range checking to osmo_rsl2sitype or check it in common/rsl.c of osmo-bts. diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 62d2af9..9e2d4bb 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -135,7 +135,7 @@ uint8_t *lchan_sacch_get(struct gsm_lchan *lchan, struct gsm_time *g_time) { uint32_t tmp; - for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % 32) { + for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % _MAX_SYSINFO_TYPE) { if (lchan->si.valid & (1 << tmp)) { lchan->si.last = tmp; return lchan->si.buf[tmp]; From laforge at gnumonks.org Sun Jan 12 18:13:35 2014 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 12 Jan 2014 19:13:35 +0100 Subject: RFC fix last coverity report with SI handling in osmo-bts In-Reply-To: <20140102193554.GB8055@xiaoyu.lan> References: <20140102193554.GB8055@xiaoyu.lan> Message-ID: <20140112181335.GP23594@nataraja> Hi Holger, On Thu, Jan 02, 2014 at 08:35:54PM +0100, Holger Hans Peter Freyther wrote: > osmo_rsl2sitype takes an uint8_t but makes no range checking, same > goes for osmo_sitype2rsl. > > I plan to apply the below patch for osmo-bts. I see no problem with that. > This would resolve the last open Coverity report for osmo-bts. It > would be nice if we could add range checking to osmo_rsl2sitype or > check it in common/rsl.c of osmo-bts. The osmo_rsl2sitype(uint8_5 rsl_si) function is using the rsl_si as index into the rsl2sitype[256] array, so it cannot cause any array out of bounds access, from what I can tell. If we add range checking, then we would also have to specify an error return code that would express the error from having occurred. So far, SYSINFO_TYPE_NONE is defined as zero, i.e. will be returned for every value between _MAX_SYSINFO_TYPE and 265. As for osmo_sitype2rsl: Yes, indeed, if you pass a value outside the enum osmo_sysinfo_type into the function, we may index sitype2rsl[] out of bounds. The question is what to return? RSL of course has no definition for a RSL_SYSTEM_INFO_INVALID or the like. So unless we change the function prototype to return an integer type, we cannot return -1... 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 jerlbeck at sysmocom.de Tue Jan 7 11:07:16 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:16 +0100 Subject: [PATCH] sms: Fix gsm_7bit legacy functions return value Message-ID: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> The legacy 7bit conversion functions (those without the '_n_' in the name) gave wrong return values on 64 bit platforms due to unproper signed/unsigned conversions and the usage of SIZE_MAX. This patch fixes this by using a smaller max size (see GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, currently set to 64k) for the legacy wrappers and by using unsigned int for max_septets. In addition, there are tests now that check the return values of legacy encoding and decoding. Sponsored-by: On-Waves ehf --- include/osmocom/gsm/gsm_utils.h | 3 +++ src/gsm/gsm_utils.c | 17 +++++++++++------ tests/sms/sms_test.c | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/osmocom/gsm/gsm_utils.h b/include/osmocom/gsm/gsm_utils.h index f412e3e..02bfe4c 100644 --- a/include/osmocom/gsm/gsm_utils.h +++ b/include/osmocom/gsm/gsm_utils.h @@ -195,6 +195,9 @@ enum gsm_chan_t { }; /* Deprectated functions */ +/* Limit encoding and decoding to use no more than this amount of buffer bytes */ +#define GSM_7BIT_LEGACY_MAX_BUFFER_SIZE 0x10000 + int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n() instead"); int gsm_7bit_decode_ussd(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n_ussd() instead"); int gsm_7bit_encode(uint8_t *result, const char *data) OSMO_DEPRECATED("Use gsm_7bit_encode_n() instead"); diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index 5241c91..198ec69 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -273,7 +273,7 @@ int gsm_7bit_encode_n(uint8_t *result, size_t n, const char *data, int *octets) { int y = 0; int o; - int max_septets = n * 8 / 7; + size_t max_septets = n * 8 / 7; /* prepare for the worst case, every character expanding to two bytes */ uint8_t *rdata = calloc(strlen(data) * 2, sizeof(uint8_t)); @@ -683,7 +683,8 @@ uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type) int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l) { - gsm_7bit_decode_n(text, SIZE_MAX, user_data, septet_l); + gsm_7bit_decode_n(text, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + user_data, septet_l); /* Mimic the original behaviour. */ return septet_l; @@ -691,21 +692,25 @@ int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l) int gsm_7bit_decode_ussd(char *text, const uint8_t *user_data, uint8_t length) { - return gsm_7bit_decode_n_ussd(text, SIZE_MAX, user_data, length); + return gsm_7bit_decode_n_ussd(text, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + user_data, length); } int gsm_7bit_encode(uint8_t *result, const char *data) { int out; - return gsm_7bit_encode_n(result, SIZE_MAX, data, &out); + return gsm_7bit_encode_n(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, &out); } int gsm_7bit_encode_ussd(uint8_t *result, const char *data, int *octets) { - return gsm_7bit_encode_n_ussd(result, SIZE_MAX, data, octets); + return gsm_7bit_encode_n_ussd(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, octets); } int gsm_7bit_encode_oct(uint8_t *result, const char *data, int *octets) { - return gsm_7bit_encode_n(result, SIZE_MAX, data, octets); + return gsm_7bit_encode_n(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, octets); } diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c index 2c9d8d8..755b321 100644 --- a/tests/sms/sms_test.c +++ b/tests/sms/sms_test.c @@ -280,6 +280,17 @@ int main(int argc, char** argv) /* test 7-bit encoding */ for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { + /* Test legacy function (return value only) */ + septet_length = gsm_7bit_encode(coded, + (const char *) test_encode[i].input); + printf("Legacy encode case %d: " + "septet length %d (expected %d)\n" + , i + , septet_length, test_encode[i].expected_septet_length + ); + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); + + /* Test new function */ memset(coded, 0x42, sizeof(coded)); septet_length = gsm_7bit_encode_n(coded, sizeof(coded), (const char *) test_encode[i].input, @@ -296,6 +307,7 @@ int main(int argc, char** argv) OSMO_ASSERT (octets_written == test_encode[i].expected_octet_length); OSMO_ASSERT (octets_written == computed_octet_length); OSMO_ASSERT (memcmp(coded, test_encode[i].expected, octets_written) == 0); + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); /* check buffer limiting */ memset(coded, 0xaa, sizeof(coded)); @@ -357,6 +369,16 @@ int main(int argc, char** argv) /* test 7-bit decoding */ for (i = 0; i < ARRAY_SIZE(test_decode); ++i) { + /* Test legacy function (return value only) */ + if (!test_decode[i].ud_hdr_ind) { + nchars = gsm_7bit_decode(result, test_decode[i].input, + test_decode[i].expected_septet_length); + printf("Legacy decode case %d: " + "return value %d (expected %d)\n", + i, nchars, test_decode[i].expected_septet_length); + } + + /* Test new function */ memset(result, 0x42, sizeof(result)); nchars = gsm_7bit_decode_n_hdr(result, sizeof(result), test_decode[i].input, test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 12:39:24 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 13:39:24 +0100 Subject: [PATCH] sms: Fix gsm_7bit legacy functions return value In-Reply-To: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389098364-19096-1-git-send-email-jerlbeck@sysmocom.de> The legacy 7bit conversion functions (those without the '_n_' in the name) gave wrong return values on 64 bit platforms due to unproper signed/unsigned conversions and the usage of SIZE_MAX. This patch fixes this by using a smaller max size (see GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, currently set to 64k) for the legacy wrappers and by using unsigned int for max_septets. In addition, there are tests now that check the return values of legacy encoding and decoding. Sponsored-by: On-Waves ehf --- include/osmocom/gsm/gsm_utils.h | 3 +++ src/gsm/gsm_utils.c | 17 +++++++++++------ tests/sms/sms_test.c | 22 ++++++++++++++++++++++ tests/sms/sms_test.ok | 8 ++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/include/osmocom/gsm/gsm_utils.h b/include/osmocom/gsm/gsm_utils.h index f412e3e..02bfe4c 100644 --- a/include/osmocom/gsm/gsm_utils.h +++ b/include/osmocom/gsm/gsm_utils.h @@ -195,6 +195,9 @@ enum gsm_chan_t { }; /* Deprectated functions */ +/* Limit encoding and decoding to use no more than this amount of buffer bytes */ +#define GSM_7BIT_LEGACY_MAX_BUFFER_SIZE 0x10000 + int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n() instead"); int gsm_7bit_decode_ussd(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n_ussd() instead"); int gsm_7bit_encode(uint8_t *result, const char *data) OSMO_DEPRECATED("Use gsm_7bit_encode_n() instead"); diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index 5241c91..198ec69 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -273,7 +273,7 @@ int gsm_7bit_encode_n(uint8_t *result, size_t n, const char *data, int *octets) { int y = 0; int o; - int max_septets = n * 8 / 7; + size_t max_septets = n * 8 / 7; /* prepare for the worst case, every character expanding to two bytes */ uint8_t *rdata = calloc(strlen(data) * 2, sizeof(uint8_t)); @@ -683,7 +683,8 @@ uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type) int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l) { - gsm_7bit_decode_n(text, SIZE_MAX, user_data, septet_l); + gsm_7bit_decode_n(text, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + user_data, septet_l); /* Mimic the original behaviour. */ return septet_l; @@ -691,21 +692,25 @@ int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l) int gsm_7bit_decode_ussd(char *text, const uint8_t *user_data, uint8_t length) { - return gsm_7bit_decode_n_ussd(text, SIZE_MAX, user_data, length); + return gsm_7bit_decode_n_ussd(text, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + user_data, length); } int gsm_7bit_encode(uint8_t *result, const char *data) { int out; - return gsm_7bit_encode_n(result, SIZE_MAX, data, &out); + return gsm_7bit_encode_n(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, &out); } int gsm_7bit_encode_ussd(uint8_t *result, const char *data, int *octets) { - return gsm_7bit_encode_n_ussd(result, SIZE_MAX, data, octets); + return gsm_7bit_encode_n_ussd(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, octets); } int gsm_7bit_encode_oct(uint8_t *result, const char *data, int *octets) { - return gsm_7bit_encode_n(result, SIZE_MAX, data, octets); + return gsm_7bit_encode_n(result, GSM_7BIT_LEGACY_MAX_BUFFER_SIZE, + data, octets); } diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c index 2c9d8d8..755b321 100644 --- a/tests/sms/sms_test.c +++ b/tests/sms/sms_test.c @@ -280,6 +280,17 @@ int main(int argc, char** argv) /* test 7-bit encoding */ for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { + /* Test legacy function (return value only) */ + septet_length = gsm_7bit_encode(coded, + (const char *) test_encode[i].input); + printf("Legacy encode case %d: " + "septet length %d (expected %d)\n" + , i + , septet_length, test_encode[i].expected_septet_length + ); + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); + + /* Test new function */ memset(coded, 0x42, sizeof(coded)); septet_length = gsm_7bit_encode_n(coded, sizeof(coded), (const char *) test_encode[i].input, @@ -296,6 +307,7 @@ int main(int argc, char** argv) OSMO_ASSERT (octets_written == test_encode[i].expected_octet_length); OSMO_ASSERT (octets_written == computed_octet_length); OSMO_ASSERT (memcmp(coded, test_encode[i].expected, octets_written) == 0); + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); /* check buffer limiting */ memset(coded, 0xaa, sizeof(coded)); @@ -357,6 +369,16 @@ int main(int argc, char** argv) /* test 7-bit decoding */ for (i = 0; i < ARRAY_SIZE(test_decode); ++i) { + /* Test legacy function (return value only) */ + if (!test_decode[i].ud_hdr_ind) { + nchars = gsm_7bit_decode(result, test_decode[i].input, + test_decode[i].expected_septet_length); + printf("Legacy decode case %d: " + "return value %d (expected %d)\n", + i, nchars, test_decode[i].expected_septet_length); + } + + /* Test new function */ memset(result, 0x42, sizeof(result)); nchars = gsm_7bit_decode_n_hdr(result, sizeof(result), test_decode[i].input, test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok index a71567d..fa536ea 100644 --- a/tests/sms/sms_test.ok +++ b/tests/sms/sms_test.ok @@ -1,11 +1,19 @@ SMS testing +Legacy encode case 0: septet length 9 (expected 9) Encode case 0: Octet length 8 (expected 8, computed 8), septet length 9 (expected 9) +Legacy encode case 1: septet length 41 (expected 41) Encode case 1: Octet length 36 (expected 36, computed 36), septet length 41 (expected 41) +Legacy encode case 2: septet length 39 (expected 39) Encode case 2: Octet length 35 (expected 35, computed 35), septet length 39 (expected 39) +Legacy encode case 3: septet length 40 (expected 40) Encode case 3: Octet length 35 (expected 35, computed 35), septet length 40 (expected 40) +Legacy decode case 0: return value 9 (expected 9) Decode case 0: return value 9 (expected 9) +Legacy decode case 1: return value 41 (expected 41) Decode case 1: return value 40 (expected 40) +Legacy decode case 2: return value 39 (expected 39) Decode case 2: return value 31 (expected 31) +Legacy decode case 3: return value 40 (expected 40) Decode case 3: return value 32 (expected 32) Decode case 4: return value 153 (expected 153) Decode case 5: return value 40 (expected 40) -- 1.7.9.5 From holger at freyther.de Wed Jan 8 09:38:05 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 8 Jan 2014 10:38:05 +0100 Subject: [PATCH] sms: Fix gsm_7bit legacy functions return value In-Reply-To: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140108093805.GA29279@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:07:16PM +0100, Jacob Erlbeck wrote: > The legacy 7bit conversion functions (those without the '_n_' in the > name) gave wrong return values on 64 bit platforms due to unproper > signed/unsigned conversions and the usage of SIZE_MAX. yes. it was a fun issue and it triggered an 'issue' in the msgb_put as well. if (msgb_tailroom(msgb) < (int) len) MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", msgb_tailroom(msgb), len); So when called with a big number the above assert will never hit and we happily create a huge MSGB.. > for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { > + /* Test legacy function (return value only) */ > + septet_length = gsm_7bit_encode(coded, > + (const char *) test_encode[i].input); > + printf("Legacy encode case %d: " > + "septet length %d (expected %d)\n" > + , i > + , septet_length, test_encode[i].expected_septet_length > + ); > + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); > + > + /* Test new function */ > memset(coded, 0x42, sizeof(coded)); I think we should do the memset before the first encode/decode as well. Do you mind if I update the patch for that? From jerlbeck at sysmocom.de Wed Jan 8 11:33:48 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 08 Jan 2014 12:33:48 +0100 Subject: [PATCH] sms: Fix gsm_7bit legacy functions return value In-Reply-To: <20140108093805.GA29279@xiaoyu.lan> References: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> <20140108093805.GA29279@xiaoyu.lan> Message-ID: <52CD379C.5000803@sysmocom.de> On 08.01.2014 10:38, Holger Hans Peter Freyther wrote: > On Tue, Jan 07, 2014 at 12:07:16PM +0100, Jacob Erlbeck wrote: >> for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { >> + /* Test legacy function (return value only) */ >> + septet_length = gsm_7bit_encode(coded, >> + (const char *) test_encode[i].input); >> + printf("Legacy encode case %d: " >> + "septet length %d (expected %d)\n" >> + , i >> + , septet_length, test_encode[i].expected_septet_length >> + ); >> + OSMO_ASSERT (septet_length == test_encode[i].expected_septet_length); >> + >> + /* Test new function */ >> memset(coded, 0x42, sizeof(coded)); > > I think we should do the memset before the first encode/decode as well. > Do you mind if I update the patch for that? The data that is written to 'coded' by gsm_7bit_encode() is not checked so initialising it wouldn't change anything since it will not been read before the existing memset(). So I would only add it when the encoded data is verified, too. This would mean using gsm_7bit_encode_oct() instead of gsm_7bit_encode() and copying the OSME_ASSERT with the call to memcmp(). Jacob From holger at freyther.de Thu Jan 9 07:20:33 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 9 Jan 2014 08:20:33 +0100 Subject: [PATCH] sms: Fix gsm_7bit legacy functions return value In-Reply-To: <52CD379C.5000803@sysmocom.de> References: <1389092836-15143-1-git-send-email-jerlbeck@sysmocom.de> <20140108093805.GA29279@xiaoyu.lan> <52CD379C.5000803@sysmocom.de> Message-ID: <20140109072033.GE3546@xiaoyu.lan> On Wed, Jan 08, 2014 at 12:33:48PM +0100, Jacob Erlbeck wrote: > > I think we should do the memset before the first encode/decode as well. > > Do you mind if I update the patch for that? > > The data that is written to 'coded' by gsm_7bit_encode() is not checked > so initialising it wouldn't change anything since it will not been read > before the existing memset(). So I would only add it when the encoded > data is verified, too. This would mean using gsm_7bit_encode_oct() > instead of gsm_7bit_encode() and copying the OSME_ASSERT with the call > to memcmp(). Okay. the question then is if we should look at the result of the encode function and I remember that you have asked me the question. Yes, we can assume that the old and 'n' function provide the same result. I am applying your change now. holger From jerlbeck at sysmocom.de Tue Jan 7 11:07:43 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:43 +0100 Subject: [PATCH 1/9] mgcp/rtp: Refactor mgcp_send to avoid code duplication Message-ID: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Currently there are two symmetric code paths which are selected by the packet destination (NET or BTS). This patch introduces 3 variables that take the different values and unifies both code paths into one. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 50 ++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 657019e..1c7c3da 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -537,6 +537,10 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, struct sockaddr_in *addr, char *buf, int rc) { struct mgcp_trunk_config *tcfg = endp->tcfg; + struct mgcp_rtp_end *rtp_end; + struct mgcp_rtp_state *rtp_state; + int tap_idx; + /* For loop toggle the destination and then dispatch. */ if (tcfg->audio_loop) dest = !dest; @@ -546,35 +550,25 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, dest = !dest; if (dest == MGCP_DEST_NET) { - if (is_rtp) { - mgcp_patch_and_count(endp, &endp->bts_state, - &endp->net_end, - addr, buf, rc); - forward_data(endp->net_end.rtp.fd, - &endp->taps[MGCP_TAP_NET_OUT], buf, rc); - return mgcp_udp_send(endp->net_end.rtp.fd, - &endp->net_end.addr, - endp->net_end.rtp_port, buf, rc); - } else if (!tcfg->omit_rtcp) { - return mgcp_udp_send(endp->net_end.rtcp.fd, - &endp->net_end.addr, - endp->net_end.rtcp_port, buf, rc); - } + rtp_end = &endp->net_end; + rtp_state = &endp->bts_state; + tap_idx = MGCP_TAP_NET_OUT; } else { - if (is_rtp) { - mgcp_patch_and_count(endp, &endp->net_state, - &endp->bts_end, - addr, buf, rc); - forward_data(endp->bts_end.rtp.fd, - &endp->taps[MGCP_TAP_BTS_OUT], buf, rc); - return mgcp_udp_send(endp->bts_end.rtp.fd, - &endp->bts_end.addr, - endp->bts_end.rtp_port, buf, rc); - } else if (!tcfg->omit_rtcp) { - return mgcp_udp_send(endp->bts_end.rtcp.fd, - &endp->bts_end.addr, - endp->bts_end.rtcp_port, buf, rc); - } + rtp_end = &endp->bts_end; + rtp_state = &endp->net_state; + tap_idx = MGCP_TAP_BTS_OUT; + } + + if (is_rtp) { + mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, rc); + forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx], buf, rc); + return mgcp_udp_send(rtp_end->rtp.fd, + &rtp_end->addr, + rtp_end->rtp_port, buf, rc); + } else if (!tcfg->omit_rtcp) { + return mgcp_udp_send(rtp_end->rtcp.fd, + &rtp_end->addr, + rtp_end->rtcp_port, buf, rc); } return 0; -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 11:07:44 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:44 +0100 Subject: [PATCH 2/9] mgcp/rtp: Add flag to disable RTP output In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-2-git-send-email-jerlbeck@sysmocom.de> This patch make it possible to have a valid endpoint that drops all outgoing RTP packets. The number of dropped packets is shown by the VTY 'show mgcp' command. By default, this feature is disabled. To enable packet dropping, the corresponding output_enabled field must be set to 0. Ticket: OW#1044 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 2 ++ openbsc/src/libmgcp/mgcp_network.c | 4 +++- openbsc/src/libmgcp/mgcp_protocol.c | 2 ++ openbsc/src/libmgcp/mgcp_vty.c | 8 +++++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index a9ae33c..b4899e4 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -71,6 +71,7 @@ struct mgcp_rtp_end { /* statistics */ unsigned int packets; unsigned int octets; + unsigned int dropped_packets; struct in_addr addr; /* in network byte order */ @@ -84,6 +85,7 @@ struct mgcp_rtp_end { int frames_per_packet; uint32_t packet_duration_ms; char *fmtp_extra; + int output_enabled; /* RTP patching */ int force_constant_ssrc; /* -1: always, 0: don't, 1: once */ diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 1c7c3da..21d52b5 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -559,7 +559,9 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, tap_idx = MGCP_TAP_BTS_OUT; } - if (is_rtp) { + if (!rtp_end->output_enabled) + rtp_end->dropped_packets += 1; + else if (is_rtp) { mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, rc); forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx], buf, rc); return mgcp_udp_send(rtp_end->rtp.fd, diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index ddec44d..95f3910 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -1178,6 +1178,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->packets = 0; end->octets = 0; + end->dropped_packets = 0; memset(&end->addr, 0, sizeof(end->addr)); end->rtp_port = end->rtcp_port = 0; end->payload_type = -1; @@ -1191,6 +1192,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->frames_per_packet = 0; /* unknown */ end->packet_duration_ms = DEFAULT_RTP_AUDIO_PACKET_DURATION_MS; end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; + end->output_enabled = 1; } static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 8411b4a..3f1ebeb 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -150,7 +150,7 @@ static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int verbo endp->trans_net.packets, endp->trans_bts.packets, VTY_NEWLINE); - if (verbose) + if (verbose) { vty_out(vty, " Timestamp Errs: BTS %d->%d, Net %d->%d%s", endp->bts_state.in_stream.err_ts_counter, @@ -158,6 +158,12 @@ static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int verbo endp->net_state.in_stream.err_ts_counter, endp->net_state.out_stream.err_ts_counter, VTY_NEWLINE); + vty_out(vty, + " Dropped Packets: Net->BTS %d, BTS->Net %d%s", + endp->bts_end.dropped_packets, + endp->net_end.dropped_packets, + VTY_NEWLINE); + } } } -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 11:07:45 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:45 +0100 Subject: [PATCH 3/9] mgcp/test: Test the connection mode parser In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-3-git-send-email-jerlbeck@sysmocom.de> This modifies the test MGCP messages to include M:recvonly (CRCX), M:sendrecv (MDCX) and M:sendonly (MDCX) outputs the resulting output_enabled flags and the conn_mode after processing the message. Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 38 ++++++++++++++++++++++++++++++++++++-- openbsc/tests/mgcp/mgcp_test.ok | 15 ++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 3cfc183..7653a0d 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -84,6 +84,7 @@ static void test_strline(void) "a=rtpmap:126 AMR/8000\r\n" \ "a=ptime:20\r\n" #define MDCX4 "MDCX 18983216 1 at mgw MGCP 1.0\r\n" \ + "M: sendrecv\r" \ "C: 2\r\n" \ "I: 1\r\n" \ "L: p:20, a:AMR, nt:IN\r\n" \ @@ -107,6 +108,7 @@ static void test_strline(void) "a=ptime:20\r\n" #define MDCX4_PT1 "MDCX 18983217 1 at mgw MGCP 1.0\r\n" \ + "M: sendrecv\r" \ "C: 2\r\n" \ "I: 1\r\n" \ "L: p:20-40, a:AMR, nt:IN\r\n" \ @@ -120,6 +122,7 @@ static void test_strline(void) "a=ptime:40\r\n" #define MDCX4_PT2 "MDCX 18983218 1 at mgw MGCP 1.0\r\n" \ + "M: sendrecv\r" \ "C: 2\r\n" \ "I: 1\r\n" \ "L: p:20-20, a:AMR, nt:IN\r\n" \ @@ -133,6 +136,7 @@ static void test_strline(void) "a=ptime:40\r\n" #define MDCX4_PT3 "MDCX 18983219 1 at mgw MGCP 1.0\r\n" \ + "M: sendrecv\r" \ "C: 2\r\n" \ "I: 1\r\n" \ "L: a:AMR, nt:IN\r\n" \ @@ -145,6 +149,20 @@ static void test_strline(void) "a=rtpmap:99 AMR/8000\r\n" \ "a=ptime:40\r\n" +#define MDCX4_SO "MDCX 18983220 1 at mgw MGCP 1.0\r\n" \ + "M: sendonly\r" \ + "C: 2\r\n" \ + "I: 1\r\n" \ + "L: p:20, a:AMR, nt:IN\r\n" \ + "\n" \ + "v=0\r\n" \ + "o=- 1 23 IN IP4 0.0.0.0\r\n" \ + "c=IN IP4 0.0.0.0\r\n" \ + "t=0 0\r\n" \ + "m=audio 4441 RTP/AVP 99\r\n" \ + "a=rtpmap:99 AMR/8000\r\n" \ + "a=ptime:40\r\n" + #define SHORT2 "CRCX 1" #define SHORT2_RET "510 000000 FAIL\r\n" #define SHORT3 "CRCX 1 1 at mgw" @@ -152,7 +170,7 @@ static void test_strline(void) #define SHORT5 "CRCX 1 1 at mgw MGCP 1.0" #define CRCX "CRCX 2 1 at mgw MGCP 1.0\r\n" \ - "M: sendrecv\r\n" \ + "M: recvonly\r\n" \ "C: 2\r\n" \ "L: p:20\r\n" \ "\r\n" \ @@ -174,7 +192,7 @@ static void test_strline(void) "a=ptime:20\r\n" #define CRCX_ZYN "CRCX 2 1 at mgw MGCP 1.0\r" \ - "M: sendrecv\r" \ + "M: recvonly\r" \ "C: 2\r\r" \ "v=0\r" \ "c=IN IP4 123.12.12.123\r" \ @@ -233,6 +251,7 @@ static const struct mgcp_test tests[] = { { "MDCX4_PT1", MDCX4_PT1, MDCX4_RET("18983217"), 99, 126 }, { "MDCX4_PT2", MDCX4_PT2, MDCX4_RET("18983218"), 99, 126 }, { "MDCX4_PT3", MDCX4_PT3, MDCX4_RET("18983219"), 99, 126 }, + { "MDCX4_SO", MDCX4_SO, MDCX4_RET("18983220"), 99, 126 }, { "DLCX", DLCX, DLCX_RET, -1, -1 }, { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, 97, 126 }, { "EMPTY", EMPTY, EMPTY_RET }, @@ -294,6 +313,9 @@ static void test_messages(void) endp = &cfg->trunk.endpoints[i]; endp->net_end.payload_type = PTYPE_NONE; endp->net_end.packet_duration_ms = -1; + endp->bts_end.output_enabled = 0; + endp->net_end.output_enabled = 0; + endp->conn_mode = -1; } for (i = 0; i < ARRAY_SIZE(tests); i++) { @@ -332,7 +354,19 @@ static void test_messages(void) else printf("Requested packetization period not set\n"); + if (endp->conn_mode != -1) + printf("Connection mode: %d, " + "BTS output %sabled, NET output %sabled\n", + endp->conn_mode, + endp->bts_end.output_enabled ? "en" : "dis", + endp->net_end.output_enabled ? "en" : "dis"); + else + printf("Connection mode not set\n"); + endp->net_end.packet_duration_ms = -1; + endp->bts_end.output_enabled = 0; + endp->net_end.output_enabled = 0; + endp->conn_mode = -1; } diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 638ac92..d5fb56f 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -18,27 +18,39 @@ Testing MDCX2 Testing CRCX Detected packet duration: 40 Requested packetetization period: 20-20 +Connection mode: 1, BTS output disabled, NET output disabled Testing MDCX3 Packet duration not set Requested packetization period not set +Connection mode not set Testing MDCX4 Detected packet duration: 40 Requested packetetization period: 20-20 +Connection mode: 3, BTS output disabled, NET output disabled Testing MDCX4_PT1 Detected packet duration: 40 Requested packetetization period: 20-40 +Connection mode: 3, BTS output disabled, NET output disabled Testing MDCX4_PT2 Detected packet duration: 40 Requested packetetization period: 20-20 +Connection mode: 3, BTS output disabled, NET output disabled Testing MDCX4_PT3 Detected packet duration: 40 Requested packetization period not set +Connection mode: 3, BTS output disabled, NET output disabled +Testing MDCX4_SO +Detected packet duration: 40 +Requested packetetization period: 20-20 +Connection mode: 2, BTS output disabled, NET output disabled Testing DLCX Detected packet duration: 20 -Requested packetization period not set +Requested packetetization period: 20-20 +Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX_ZYN Packet duration not set Requested packetization period not set +Connection mode: 1, BTS output disabled, NET output disabled Testing EMPTY Testing SHORT1 Testing SHORT2 @@ -49,6 +61,7 @@ Testing RQNT2 Testing DLCX Detected packet duration: 20 Requested packetization period not set +Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX Re-transmitting CRCX Testing RQNT1 -- 1.7.9.5 From holger at freyther.de Mon Jan 13 08:52:50 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 09:52:50 +0100 Subject: [PATCH 3/9] mgcp/test: Test the connection mode parser In-Reply-To: <1389092871-15181-3-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140113085250.GU9767@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:07:45PM +0100, Jacob Erlbeck wrote: > + endp->bts_end.output_enabled = 0; > + endp->net_end.output_enabled = 0; > + endp->bts_end.output_enabled = 0; > + endp->net_end.output_enabled = 0; > +Connection mode: 1, BTS output disabled, NET output disabled It is the third time I try to write something but I don't find the right words. I am afraid that with the manipulation of internal state we move away from testing the real thing. I understand that you want to capture the effect of parsing the message once. What about assigning variables that are not within the scope of what libmgcp/ would normally use? This way we can be sure that a.) libmgcp set these variables and b.) they are what we wanted it to be set to? holger From jerlbeck at sysmocom.de Tue Jan 14 08:54:48 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 09:54:48 +0100 Subject: [PATCH 3/9] mgcp/test: Test the connection mode parser In-Reply-To: <20140113085250.GU9767@xiaoyu.lan> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-3-git-send-email-jerlbeck@sysmocom.de> <20140113085250.GU9767@xiaoyu.lan> Message-ID: <52D4FB58.8000203@sysmocom.de> On 13.01.2014 09:52, Holger Hans Peter Freyther wrote: > On Tue, Jan 07, 2014 at 12:07:45PM +0100, Jacob Erlbeck wrote: > >> + endp->bts_end.output_enabled = 0; >> + endp->net_end.output_enabled = 0; > > I am afraid that with the manipulation of internal state > we move away from testing the real thing. Hmm, that's unit testing mainly targeted at the MGCP parser. So I'm not too concerned about that, as long as I keep away from the part of the state that is really used by the parser and not only set as a side effect. > I understand that you want to capture the effect of parsing the > message once. What about assigning variables that are not within the > scope of what libmgcp/ would normally use? This way we can be sure > that a.) libmgcp set these variables and b.) they are what we wanted > it to be set to? That would be ok, what's about 42 or -1? Jacob From jerlbeck at sysmocom.de Tue Jan 7 11:07:46 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:46 +0100 Subject: [PATCH 4/9] mgcp/test: Reset pkt_period_* after each test In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-4-git-send-email-jerlbeck@sysmocom.de> Currently these value may leak into the next test. This patch will reset them after each message has been processed. Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 2 ++ openbsc/tests/mgcp/mgcp_test.ok | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 7653a0d..538dc9f 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -366,6 +366,8 @@ static void test_messages(void) endp->net_end.packet_duration_ms = -1; endp->bts_end.output_enabled = 0; endp->net_end.output_enabled = 0; + endp->local_options.pkt_period_min = 0; + endp->local_options.pkt_period_max = 0; endp->conn_mode = -1; } diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index d5fb56f..43a7402 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -45,7 +45,7 @@ Requested packetetization period: 20-20 Connection mode: 2, BTS output disabled, NET output disabled Testing DLCX Detected packet duration: 20 -Requested packetetization period: 20-20 +Requested packetization period not set Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX_ZYN Packet duration not set -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 11:07:47 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:47 +0100 Subject: [PATCH 5/9] mgcp/test: Show the number of dummy packets sent In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-5-git-send-email-jerlbeck@sysmocom.de> This patch extends the test_messages test to show the number of dummy packets that has been passed to sendto(). This way, dummy packets are even being counted when sendto() itself failes (e.g. due to the fd being -1). Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 538dc9f..7eeef99 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -16,6 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#undef _GNU_SOURCE +#define _GNU_SOURCE #include #include @@ -24,6 +26,7 @@ #include #include #include +#include char *strline_r(char *str, char **saveptr); @@ -293,6 +296,31 @@ static int mgcp_test_policy_cb(struct mgcp_trunk_config *cfg, int endpoint, return MGCP_POLICY_CONT; } +#define MGCP_DUMMY_LOAD 0x23 +static int dummy_packets = 0; +/* override and forward */ +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + typedef ssize_t (*sendto_t)(int, const void *, size_t, int, + const struct sockaddr *, socklen_t); + static sendto_t real_sendto = NULL; + uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr); + int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port); + + if (!real_sendto) + real_sendto = dlsym(RTLD_NEXT, "sendto"); + + if (len == 1 && ((const char *)buf)[0] == MGCP_DUMMY_LOAD ) { + fprintf(stderr, "Dummy packet to 0x%08x:%d, msg length %d\n%s\n\n", + dest_host, dest_port, + len, osmo_hexdump(buf, len)); + dummy_packets += 1; + } + + return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); +} + static void test_messages(void) { struct mgcp_config *cfg; @@ -326,6 +354,7 @@ static void test_messages(void) printf("Testing %s\n", t->name); last_endpoint = -1; + dummy_packets = 0; inp = create_msg(t->req); msg = mgcp_handle_message(cfg, inp); @@ -337,6 +366,9 @@ static void test_messages(void) printf("%s failed '%s'\n", t->name, (char *) msg->data); msgb_free(msg); + if (dummy_packets) + printf("Dummy packets: %d\n", dummy_packets); + if (last_endpoint != -1) { endp = &cfg->trunk.endpoints[last_endpoint]; -- 1.7.9.5 From holger at freyther.de Thu Jan 16 12:22:37 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 16 Jan 2014 13:22:37 +0100 Subject: [PATCH 5/9] mgcp/test: Show the number of dummy packets sent In-Reply-To: <1389092871-15181-5-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-5-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140116122237.GA22970@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:07:47PM +0100, Jacob Erlbeck wrote: I added: diff --git a/openbsc/tests/mgcp/Makefile.am b/openbsc/tests/mgcp/Makefile.am index 8c365b4..470cdd8 100644 --- a/openbsc/tests/mgcp/Makefile.am +++ b/openbsc/tests/mgcp/Makefile.am @@ -11,4 +11,5 @@ mgcp_test_SOURCES = mgcp_test.c mgcp_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmgcp/libmgcp.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) + $(LIBOSMOCORE_LIBS) -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \ + $(LIBRARY_DL) for the dlsym From jerlbeck at sysmocom.de Tue Jan 7 11:07:48 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:48 +0100 Subject: [PATCH 6/9] mgcp: Set output_enabled flags based on the MGCP mode In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-6-git-send-email-jerlbeck@sysmocom.de> This patch enhances parse_conn_mode() to set the output_enabled flags of each end based on the MGCP mode. Ticket: OW#1044 Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 37 ++++++++++++++++++++++++++++------- openbsc/tests/mgcp/mgcp_test.ok | 14 ++++++------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 95f3910..b55da37 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -488,22 +488,45 @@ static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *p) return create_ok_response(p->endp, 200, "AUEP", p->trans); } -static int parse_conn_mode(const char *msg, int *conn_mode) +static int parse_conn_mode(const char *msg, struct mgcp_endpoint *endp) { int ret = 0; if (strcmp(msg, "recvonly") == 0) - *conn_mode = MGCP_CONN_RECV_ONLY; + endp->conn_mode = MGCP_CONN_RECV_ONLY; else if (strcmp(msg, "sendrecv") == 0) - *conn_mode = MGCP_CONN_RECV_SEND; + endp->conn_mode = MGCP_CONN_RECV_SEND; else if (strcmp(msg, "sendonly") == 0) - *conn_mode = MGCP_CONN_SEND_ONLY; + endp->conn_mode = MGCP_CONN_SEND_ONLY; else if (strcmp(msg, "loopback") == 0) - *conn_mode = MGCP_CONN_LOOPBACK; + endp->conn_mode = MGCP_CONN_LOOPBACK; else { LOGP(DMGCP, LOGL_ERROR, "Unknown connection mode: '%s'\n", msg); ret = -1; } + switch (endp->conn_mode) { + case MGCP_CONN_NONE: + endp->net_end.output_enabled = 0; + endp->bts_end.output_enabled = 0; + break; + + case MGCP_CONN_RECV_ONLY: + endp->net_end.output_enabled = 0; + endp->bts_end.output_enabled = 1; + break; + + case MGCP_CONN_SEND_ONLY: + endp->net_end.output_enabled = 1; + endp->bts_end.output_enabled = 0; + break; + + default: + endp->net_end.output_enabled = 1; + endp->bts_end.output_enabled = 1; + break; + } + + return ret; } @@ -794,7 +817,7 @@ mgcp_header_done: set_local_cx_options(endp->tcfg->endpoints, &endp->local_options, local_options); - if (parse_conn_mode(mode, &endp->conn_mode) != 0) { + if (parse_conn_mode(mode, endp) != 0) { error_code = 517; goto error2; } @@ -895,7 +918,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) local_options = (const char *) line + 3; break; case 'M': - if (parse_conn_mode(line + 3, &endp->conn_mode) != 0) { + if (parse_conn_mode(line + 3, endp) != 0) { error_code = 517; goto error3; } diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 43a7402..6db7226 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -18,7 +18,7 @@ Testing MDCX2 Testing CRCX Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 1, BTS output disabled, NET output disabled +Connection mode: 1, BTS output enabled, NET output disabled Testing MDCX3 Packet duration not set Requested packetization period not set @@ -26,23 +26,23 @@ Connection mode not set Testing MDCX4 Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 3, BTS output disabled, NET output disabled +Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT1 Detected packet duration: 40 Requested packetetization period: 20-40 -Connection mode: 3, BTS output disabled, NET output disabled +Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT2 Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 3, BTS output disabled, NET output disabled +Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT3 Detected packet duration: 40 Requested packetization period not set -Connection mode: 3, BTS output disabled, NET output disabled +Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_SO Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 2, BTS output disabled, NET output disabled +Connection mode: 2, BTS output disabled, NET output enabled Testing DLCX Detected packet duration: 20 Requested packetization period not set @@ -50,7 +50,7 @@ Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX_ZYN Packet duration not set Requested packetization period not set -Connection mode: 1, BTS output disabled, NET output disabled +Connection mode: 1, BTS output enabled, NET output disabled Testing EMPTY Testing SHORT1 Testing SHORT2 -- 1.7.9.5 From holger at freyther.de Wed Jan 8 09:45:12 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 8 Jan 2014 10:45:12 +0100 Subject: [PATCH 6/9] mgcp: Set output_enabled flags based on the MGCP mode In-Reply-To: <1389092871-15181-6-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-6-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140108094512.GC29279@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:07:48PM +0100, Jacob Erlbeck wrote: Good Morning, > diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok > index 43a7402..6db7226 100644 > --- a/openbsc/tests/mgcp/mgcp_test.ok > +++ b/openbsc/tests/mgcp/mgcp_test.ok In the test case you force the output_enabled variable to 0. Now that the state is set based on the connection mode I think it is dangerous to set the state inside the testcase. mgcp_free_endpoint should reset it and we should rely and test that. What do you think? From jerlbeck at sysmocom.de Wed Jan 8 12:06:56 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 08 Jan 2014 13:06:56 +0100 Subject: [PATCH 6/9] mgcp: Set output_enabled flags based on the MGCP mode In-Reply-To: <20140108094512.GC29279@xiaoyu.lan> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-6-git-send-email-jerlbeck@sysmocom.de> <20140108094512.GC29279@xiaoyu.lan> Message-ID: <52CD3F60.1090506@sysmocom.de> On 08.01.2014 10:45, Holger Hans Peter Freyther wrote: > On Tue, Jan 07, 2014 at 12:07:48PM +0100, Jacob Erlbeck wrote: > > Good Morning, > >> diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok >> index 43a7402..6db7226 100644 >> --- a/openbsc/tests/mgcp/mgcp_test.ok >> +++ b/openbsc/tests/mgcp/mgcp_test.ok > > > In the test case you force the output_enabled variable to 0. Now that > the state is set based on the connection mode I think it is dangerous > to set the state inside the testcase. mgcp_free_endpoint should reset > it and we should rely and test that. > > What do you think? > We cannot use mgcp_free_endp() there without additional changes in the testing framework, since this would clear flags like ci too, thus breaking e.g. MDCX handling. The order of the test messages is relevant and part of the state must be kept. In addition, mgcp_free_endp() initialises the output_enabled flags to 1 which would make it difficult to check whether sendrecv has been detected successfully. Of course this raises the question, whether it in sensible to set them to 1 at initialisation. While it maintains semantic compatibility, these flags are not in sync with conn_mode after init. Jacob From holger at freyther.de Mon Jan 13 08:32:55 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 09:32:55 +0100 Subject: [PATCH 6/9] mgcp: Set output_enabled flags based on the MGCP mode In-Reply-To: <52CD3F60.1090506@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-6-git-send-email-jerlbeck@sysmocom.de> <20140108094512.GC29279@xiaoyu.lan> <52CD3F60.1090506@sysmocom.de> Message-ID: <20140113083255.GT9767@xiaoyu.lan> On Wed, Jan 08, 2014 at 01:06:56PM +0100, Jacob Erlbeck wrote: Good Morning! > We cannot use mgcp_free_endp() there without additional changes in the > testing framework, since this would clear flags like ci too, thus > breaking e.g. MDCX handling. The order of the test messages is relevant > and part of the state must be kept. That is a valid argument. On the other hand the further we go away from the normal allocation/init procedure of an endpoint the more we test something that does not relate to the real world. What other state do we rely on besides the CI? > In addition, mgcp_free_endp() initialises the output_enabled flags to 1 > which would make it difficult to check whether sendrecv has been > detected successfully. Of course this raises the question, whether it in > sensible to set them to 1 at initialisation. While it maintains semantic > compatibility, these flags are not in sync with conn_mode after init. That is true. I have a local refactoring backlog to make mgcp_free_endp free some resources and have a separate mgcp_init_endp to initialize it just after the allocation. :} From jerlbeck at sysmocom.de Tue Jan 7 11:07:49 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:49 +0100 Subject: [PATCH 7/9] mgcp/rtp: Make offset computation understandable In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-7-git-send-email-jerlbeck@sysmocom.de> Rename the timestamp variable to make in clear, that the input timestamp is meant. Add a helper variable to illustrate the offset computation. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 21d52b5..04e6cbe 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -241,10 +241,11 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, - int16_t delta_seq, uint32_t timestamp) + int16_t delta_seq, uint32_t in_timestamp) { int32_t tsdelta = state->packet_duration; int timestamp_offset; + uint32_t out_timestamp; if (tsdelta == 0) { tsdelta = state->out_stream.last_tsdelta; @@ -269,9 +270,8 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp, } } - timestamp_offset = - state->out_stream.last_timestamp - timestamp + - delta_seq * tsdelta; + out_timestamp = state->out_stream.last_timestamp + delta_seq * tsdelta; + timestamp_offset = out_timestamp - in_timestamp; if (state->timestamp_offset != timestamp_offset) { state->timestamp_offset = timestamp_offset; -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 11:07:50 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:50 +0100 Subject: [PATCH 8/9] mgcp/rtp: Send dummy packet to the RTCP destination, too In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-8-git-send-email-jerlbeck@sysmocom.de> Currently a dummy packet is only sent to the RTP port. This is not enough if RTCP must also cross the SNAT. This patch sends an additional dummy packet to the RTCP net destination if omit_rtcp is not set. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 04e6cbe..0cc2041 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -129,9 +129,16 @@ static int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int mgcp_send_dummy(struct mgcp_endpoint *endp) { static char buf[] = { MGCP_DUMMY_LOAD }; + int rc; + + rc = mgcp_udp_send(endp->net_end.rtp.fd, &endp->net_end.addr, + endp->net_end.rtp_port, buf, 1); + + if (rc == -1 || endp->tcfg->omit_rtcp) + return rc; - return mgcp_udp_send(endp->net_end.rtp.fd, &endp->net_end.addr, - endp->net_end.rtp_port, buf, 1); + return mgcp_udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr, + endp->net_end.rtcp_port, buf, 1); } static int32_t compute_timestamp_aligment_error(struct mgcp_rtp_stream_state *sstate, -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 7 11:07:51 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Jan 2014 12:07:51 +0100 Subject: [PATCH 9/9] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> So far, a single dummy packet has been sent immediately after the reception of a MDCX message. There is no dedicated keep alive mechanism (it just worked because the audio from the MS has always been forwarded to the NAT until the 'mgcp: Set output_enabled flags based on the MGCP mode' patch). This patch adds explicit, timer based keep alive handling that can be enable per trunk. A VTY command 'rtp keep-alive' command is added for configuration which can be used to set the interval in seconds, to send a single packet after the reception of a CRCX/MDCX when RTP data from the net is expected ('once'), or to disable the feature completely ('no rtp keep-alive'). The default is 'once'. Note that this removes the mgcp_change_cb() from mgcp_main.c. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp.h | 9 ++++ openbsc/src/libmgcp/mgcp_protocol.c | 43 +++++++++++++++++ openbsc/src/libmgcp/mgcp_vty.c | 86 +++++++++++++++++++++++++++++++++ openbsc/src/osmo-bsc_mgcp/mgcp_main.c | 10 ---- openbsc/tests/mgcp/mgcp_test.ok | 6 +++ 5 files changed, 144 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 335c83d..1d74078 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -25,6 +25,7 @@ #include #include +#include #include "debug.h" @@ -103,6 +104,8 @@ struct mgcp_port_range { int last_port; }; +#define MGCP_KEEPALIVE_ONCE (-1) + struct mgcp_trunk_config { struct llist_head entry; @@ -118,6 +121,7 @@ struct mgcp_trunk_config { int audio_loop; int omit_rtcp; + int keepalive_interval; /* RTP patching */ int force_constant_ssrc; /* 0: don't, 1: once */ @@ -126,6 +130,9 @@ struct mgcp_trunk_config { /* spec handling */ int force_realloc; + /* timer */ + struct osmo_timer_list keepalive_timer; + unsigned int number_endpoints; struct mgcp_endpoint *endpoints; }; @@ -187,6 +194,8 @@ int mgcp_reset_transcoder(struct mgcp_config *cfg); void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size); int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter); +void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval); + /* * format helper functions */ diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index b55da37..8f6b7c2 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -877,6 +877,9 @@ mgcp_header_done: if (p->cfg->change_cb) p->cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX); + if (endp->bts_end.output_enabled && tcfg->keepalive_interval != 0) + mgcp_send_dummy(endp); + create_transcoder(endp); return create_response_with_sdp(endp, "CRCX", p->trans); error2: @@ -975,6 +978,10 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port)); if (p->cfg->change_cb) p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX); + + if (endp->bts_end.output_enabled && endp->tcfg->keepalive_interval != 0) + mgcp_send_dummy(endp); + if (silent) goto out_silent; @@ -1127,6 +1134,40 @@ static struct msgb *handle_noti_req(struct mgcp_parse_data *p) create_err_response(p->endp, res, "RQNT", p->trans); } +static void mgcp_keepalive_timer_cb(void *_tcfg) +{ + struct mgcp_trunk_config *tcfg = _tcfg; + int i; + LOGP(DMGCP, LOGL_DEBUG, "Triggered trunk %d keepalive timer.\n", + tcfg->trunk_nr); + + if (tcfg->keepalive_interval <= 0) + return; + + for (i = 1; i < tcfg->number_endpoints; ++i) { + struct mgcp_endpoint *endp = &tcfg->endpoints[i]; + if (endp->bts_end.output_enabled) + mgcp_send_dummy(endp); + } + + LOGP(DMGCP, LOGL_DEBUG, "Rescheduling trunk %d keepalive timer.\n", + tcfg->trunk_nr); + osmo_timer_schedule(&tcfg->keepalive_timer, tcfg->keepalive_interval, 0); +} + +void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval) +{ + tcfg->keepalive_interval = interval; + tcfg->keepalive_timer.data = tcfg; + tcfg->keepalive_timer.cb = mgcp_keepalive_timer_cb; + + if (interval <= 0) + osmo_timer_del(&tcfg->keepalive_timer); + else + osmo_timer_schedule(&tcfg->keepalive_timer, + tcfg->keepalive_interval, 0); +} + struct mgcp_config *mgcp_config_alloc(void) { struct mgcp_config *cfg; @@ -1153,6 +1194,7 @@ struct mgcp_config *mgcp_config_alloc(void) cfg->trunk.audio_payload = 126; cfg->trunk.audio_send_ptime = 1; cfg->trunk.omit_rtcp = 0; + mgcp_trunk_set_keepalive(&cfg->trunk, MGCP_KEEPALIVE_ONCE); INIT_LLIST_HEAD(&cfg->trunks); @@ -1177,6 +1219,7 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr) trunk->audio_send_ptime = 1; trunk->number_endpoints = 33; trunk->omit_rtcp = 0; + mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE); llist_add_tail(&trunk->entry, &cfg->trunks); return trunk; } diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 3f1ebeb..8004d53 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -32,6 +32,7 @@ #define RTCP_OMIT_STR "Drop RTCP packets in both directions\n" #define RTP_PATCH_STR "Modify RTP packet header in both directions\n" +#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n" static struct mgcp_config *g_cfg = NULL; @@ -85,6 +86,12 @@ static int config_write_mgcp(struct vty *vty) g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE); vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE); + if (g_cfg->trunk.keepalive_interval) + vty_out(vty, " rtp keep-alive %d%s", + g_cfg->trunk.keepalive_interval, VTY_NEWLINE); + else + vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE); + if (g_cfg->trunk.omit_rtcp) vty_out(vty, " rtcp-omit%s", VTY_NEWLINE); else @@ -511,6 +518,39 @@ DEFUN(cfg_mgcp_no_patch_rtp, return CMD_SUCCESS; } +DEFUN(cfg_mgcp_rtp_keepalive, + cfg_mgcp_rtp_keepalive_cmd, + "rtp keep-alive <1-120>", + RTP_STR RTP_KEEPALIVE_STR + "Keep alive interval in secs\n" + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_mgcp_rtp_keepalive_once, + cfg_mgcp_rtp_keepalive_once_cmd, + "rtp keep-alive once", + RTP_STR RTP_KEEPALIVE_STR + "Send keep alive once after CRCX\n" + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE); + return CMD_SUCCESS; +} + +DEFUN(cfg_mgcp_no_rtp_keepalive, + cfg_mgcp_no_rtp_keepalive_cmd, + "no rtp keep-alive", + NO_STR RTP_STR RTP_KEEPALIVE_STR + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, 0); + return CMD_SUCCESS; +} + + #define CALL_AGENT_STR "Callagent information\n" DEFUN(cfg_mgcp_agent_addr, @@ -598,6 +638,13 @@ static int config_write_trunk(struct vty *vty) trunk->audio_name, VTY_NEWLINE); vty_out(vty, " %ssdp audio-payload send-ptime%s", trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE); + + if (trunk->keepalive_interval) + vty_out(vty, " rtp keep-alive %d%s", + trunk->keepalive_interval, VTY_NEWLINE); + else + vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE); + vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE); if (trunk->omit_rtcp) @@ -780,6 +827,39 @@ DEFUN(cfg_trunk_no_patch_rtp, return CMD_SUCCESS; } +DEFUN(cfg_trunk_rtp_keepalive, + cfg_trunk_rtp_keepalive_cmd, + "rtp keep-alive <1-120>", + RTP_STR RTP_KEEPALIVE_STR + "Keepalive interval in secs\n" + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_trunk_rtp_keepalive_once, + cfg_trunk_rtp_keepalive_once_cmd, + "rtp keep-alive once", + RTP_STR RTP_KEEPALIVE_STR + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE); + return CMD_SUCCESS; +} + +DEFUN(cfg_trunk_no_rtp_keepalive, + cfg_trunk_no_rtp_keepalive_cmd, + "no rtp keep-alive", + NO_STR RTP_STR RTP_KEEPALIVE_STR + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, 0); + return CMD_SUCCESS; +} DEFUN(loop_endp, loop_endp_cmd, @@ -999,6 +1079,9 @@ int mgcp_vty_init(void) install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd); install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd); install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd); + install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd); + install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd); + install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd); install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd); install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old); install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd); @@ -1024,6 +1107,9 @@ int mgcp_vty_init(void) install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd); install_node(&trunk_node, config_write_trunk); vty_install_default(TRUNK_NODE); + install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd); + install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd); + install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old); diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c index 596ea8a..14ec221 100644 --- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c +++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c @@ -137,15 +137,6 @@ static int mgcp_rsip_cb(struct mgcp_trunk_config *tcfg) return 0; } -static int mgcp_change_cb(struct mgcp_trunk_config *cfg, int endpoint, int state) -{ - if (state != MGCP_ENDP_MDCX) - return 0; - - mgcp_send_dummy(&cfg->endpoints[endpoint]); - return 0; -} - static int read_call_agent(struct osmo_fd *fd, unsigned int what) { struct sockaddr_in addr; @@ -233,7 +224,6 @@ int main(int argc, char **argv) /* set some callbacks */ cfg->reset_cb = mgcp_rsip_cb; - cfg->change_cb = mgcp_change_cb; /* we need to bind a socket */ if (rc == 0) { diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 6db7226..7e8aa5c 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -16,6 +16,7 @@ Testing AUEP2 Testing MDCX1 Testing MDCX2 Testing CRCX +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 1, BTS output enabled, NET output disabled @@ -24,18 +25,22 @@ Packet duration not set Requested packetization period not set Connection mode not set Testing MDCX4 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT1 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-40 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT2 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT3 +Dummy packets: 1 Detected packet duration: 40 Requested packetization period not set Connection mode: 3, BTS output enabled, NET output enabled @@ -48,6 +53,7 @@ Detected packet duration: 20 Requested packetization period not set Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX_ZYN +Dummy packets: 1 Packet duration not set Requested packetization period not set Connection mode: 1, BTS output enabled, NET output disabled -- 1.7.9.5 From holger at freyther.de Mon Jan 13 08:57:24 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 13 Jan 2014 09:57:24 +0100 Subject: [PATCH 9/9] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140113085724.GV9767@xiaoyu.lan> On Tue, Jan 07, 2014 at 12:07:51PM +0100, Jacob Erlbeck wrote: > + for (i = 1; i < tcfg->number_endpoints; ++i) { > + struct mgcp_endpoint *endp = &tcfg->endpoints[i]; > + if (endp->bts_end.output_enabled) Shouldn't this code look at the connection mode? E.g. the output is enabled even in SEND_RECV mode and then we certainly don't need to send dummy packets? From jerlbeck at sysmocom.de Tue Jan 14 08:41:39 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 09:41:39 +0100 Subject: [PATCH 9/9] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <20140113085724.GV9767@xiaoyu.lan> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> <20140113085724.GV9767@xiaoyu.lan> Message-ID: <52D4F843.4040806@sysmocom.de> On 13.01.2014 09:57, Holger Hans Peter Freyther wrote: > On Tue, Jan 07, 2014 at 12:07:51PM +0100, Jacob Erlbeck wrote: > >> + for (i = 1; i < tcfg->number_endpoints; ++i) { >> + struct mgcp_endpoint *endp = &tcfg->endpoints[i]; >> + if (endp->bts_end.output_enabled) > > Shouldn't this code look at the connection mode? E.g. the output is > enabled even in SEND_RECV mode and then we certainly don't need to > send dummy packets? > If (and only if) we can rely on incoming packets from any type of BTS when SEND_RECV is used, we could optimize these few packets away. Otherwise I'd rather check, whether packets have been sent to the net since the last timeout and only send a keep alive packet if there were none. Jacob From holger at freyther.de Tue Jan 14 11:54:15 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 14 Jan 2014 12:54:15 +0100 Subject: [PATCH 9/9] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <52D4F843.4040806@sysmocom.de> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> <20140113085724.GV9767@xiaoyu.lan> <52D4F843.4040806@sysmocom.de> Message-ID: <20140114115415.GC21078@xiaoyu.lan> On Tue, Jan 14, 2014 at 09:41:39AM +0100, Jacob Erlbeck wrote: > If (and only if) we can rely on incoming packets from any type of BTS > when SEND_RECV is used, we could optimize these few packets away. > > Otherwise I'd rather check, whether packets have been sent to the net > since the last timeout and only send a keep alive packet if there were none. I disagree. Keep things simple and look at the connection state. if (and only if) we start to look into DTX we can consider adding a heuristic that checks the time of the last outgoing RTP packet. holger From jerlbeck at sysmocom.de Tue Jan 14 13:43:24 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:43:24 +0100 Subject: [PATCH 9/9] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <20140114115415.GC21078@xiaoyu.lan> References: <1389092871-15181-1-git-send-email-jerlbeck@sysmocom.de> <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> <20140113085724.GV9767@xiaoyu.lan> <52D4F843.4040806@sysmocom.de> <20140114115415.GC21078@xiaoyu.lan> Message-ID: <52D53EFC.5070906@sysmocom.de> On 14.01.2014 12:54, Holger Hans Peter Freyther wrote: > On Tue, Jan 14, 2014 at 09:41:39AM +0100, Jacob Erlbeck wrote: > >> If (and only if) we can rely on incoming packets from any type of BTS >> when SEND_RECV is used, we could optimize these few packets away. >> >> Otherwise I'd rather check, whether packets have been sent to the net >> since the last timeout and only send a keep alive packet if there were none. > > I disagree. Keep things simple and look at the connection state. if (and only > if) we start to look into DTX we can consider adding a heuristic that checks > the time of the last outgoing RTP packet. Ok, I'm convinced that my solution makes probably no difference, since keep-alive has only worked with the help of the BTS packets so far anyway. And your approach is indeed simpler and doesn't change the behaviour compared to the old inplementation. Jacob From jerlbeck at sysmocom.de Wed Jan 15 13:00:16 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:00:16 +0100 Subject: [PATCH] mgcp: Send RTP keepalive dummy packets to net In-Reply-To: <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> References: <1389092871-15181-9-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389790816-27963-1-git-send-email-jerlbeck@sysmocom.de> So far, a single dummy packet has been sent immediately after the reception of a MDCX message. There is no dedicated keep alive mechanism (it just worked because the audio from the MS has always been forwarded to the NAT until the 'mgcp: Set output_enabled flags based on the MGCP mode' patch). This patch adds explicit, timer based keep alive handling that can be enable per trunk. A VTY command 'rtp keep-alive' command is added for configuration which can be used to set the interval in seconds, to send a single packet after the reception of a CRCX/MDCX when RTP data from the net is expected ('once'), or to disable the feature completely ('no rtp keep-alive'). In 'send-recv' connections, only the initial packet is sent if enabled (even when an interval has been configured). The default is 'once'. Note that this removes the mgcp_change_cb() from mgcp_main.c. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp.h | 9 ++++ openbsc/src/libmgcp/mgcp_protocol.c | 43 ++++++++++++++++ openbsc/src/libmgcp/mgcp_vty.c | 91 +++++++++++++++++++++++++++++++++ openbsc/src/osmo-bsc_mgcp/mgcp_main.c | 10 ---- openbsc/tests/mgcp/mgcp_test.ok | 6 +++ 5 files changed, 149 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 335c83d..1d74078 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -25,6 +25,7 @@ #include #include +#include #include "debug.h" @@ -103,6 +104,8 @@ struct mgcp_port_range { int last_port; }; +#define MGCP_KEEPALIVE_ONCE (-1) + struct mgcp_trunk_config { struct llist_head entry; @@ -118,6 +121,7 @@ struct mgcp_trunk_config { int audio_loop; int omit_rtcp; + int keepalive_interval; /* RTP patching */ int force_constant_ssrc; /* 0: don't, 1: once */ @@ -126,6 +130,9 @@ struct mgcp_trunk_config { /* spec handling */ int force_realloc; + /* timer */ + struct osmo_timer_list keepalive_timer; + unsigned int number_endpoints; struct mgcp_endpoint *endpoints; }; @@ -187,6 +194,8 @@ int mgcp_reset_transcoder(struct mgcp_config *cfg); void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size); int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter); +void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval); + /* * format helper functions */ diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index b55da37..9996ba7 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -877,6 +877,9 @@ mgcp_header_done: if (p->cfg->change_cb) p->cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX); + if (endp->bts_end.output_enabled && tcfg->keepalive_interval != 0) + mgcp_send_dummy(endp); + create_transcoder(endp); return create_response_with_sdp(endp, "CRCX", p->trans); error2: @@ -975,6 +978,10 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port)); if (p->cfg->change_cb) p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX); + + if (endp->bts_end.output_enabled && endp->tcfg->keepalive_interval != 0) + mgcp_send_dummy(endp); + if (silent) goto out_silent; @@ -1127,6 +1134,40 @@ static struct msgb *handle_noti_req(struct mgcp_parse_data *p) create_err_response(p->endp, res, "RQNT", p->trans); } +static void mgcp_keepalive_timer_cb(void *_tcfg) +{ + struct mgcp_trunk_config *tcfg = _tcfg; + int i; + LOGP(DMGCP, LOGL_DEBUG, "Triggered trunk %d keepalive timer.\n", + tcfg->trunk_nr); + + if (tcfg->keepalive_interval <= 0) + return; + + for (i = 1; i < tcfg->number_endpoints; ++i) { + struct mgcp_endpoint *endp = &tcfg->endpoints[i]; + if (endp->conn_mode == MGCP_CONN_RECV_ONLY) + mgcp_send_dummy(endp); + } + + LOGP(DMGCP, LOGL_DEBUG, "Rescheduling trunk %d keepalive timer.\n", + tcfg->trunk_nr); + osmo_timer_schedule(&tcfg->keepalive_timer, tcfg->keepalive_interval, 0); +} + +void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval) +{ + tcfg->keepalive_interval = interval; + tcfg->keepalive_timer.data = tcfg; + tcfg->keepalive_timer.cb = mgcp_keepalive_timer_cb; + + if (interval <= 0) + osmo_timer_del(&tcfg->keepalive_timer); + else + osmo_timer_schedule(&tcfg->keepalive_timer, + tcfg->keepalive_interval, 0); +} + struct mgcp_config *mgcp_config_alloc(void) { struct mgcp_config *cfg; @@ -1153,6 +1194,7 @@ struct mgcp_config *mgcp_config_alloc(void) cfg->trunk.audio_payload = 126; cfg->trunk.audio_send_ptime = 1; cfg->trunk.omit_rtcp = 0; + mgcp_trunk_set_keepalive(&cfg->trunk, MGCP_KEEPALIVE_ONCE); INIT_LLIST_HEAD(&cfg->trunks); @@ -1177,6 +1219,7 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr) trunk->audio_send_ptime = 1; trunk->number_endpoints = 33; trunk->omit_rtcp = 0; + mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE); llist_add_tail(&trunk->entry, &cfg->trunks); return trunk; } diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 3f1ebeb..408a059 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -32,6 +32,7 @@ #define RTCP_OMIT_STR "Drop RTCP packets in both directions\n" #define RTP_PATCH_STR "Modify RTP packet header in both directions\n" +#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n" static struct mgcp_config *g_cfg = NULL; @@ -85,6 +86,14 @@ static int config_write_mgcp(struct vty *vty) g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE); vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE); + if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE) + vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE); + else if (g_cfg->trunk.keepalive_interval) + vty_out(vty, " rtp keep-alive %d%s", + g_cfg->trunk.keepalive_interval, VTY_NEWLINE); + else + vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE); + if (g_cfg->trunk.omit_rtcp) vty_out(vty, " rtcp-omit%s", VTY_NEWLINE); else @@ -511,6 +520,39 @@ DEFUN(cfg_mgcp_no_patch_rtp, return CMD_SUCCESS; } +DEFUN(cfg_mgcp_rtp_keepalive, + cfg_mgcp_rtp_keepalive_cmd, + "rtp keep-alive <1-120>", + RTP_STR RTP_KEEPALIVE_STR + "Keep alive interval in secs\n" + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_mgcp_rtp_keepalive_once, + cfg_mgcp_rtp_keepalive_once_cmd, + "rtp keep-alive once", + RTP_STR RTP_KEEPALIVE_STR + "Send dummy packet only once after CRCX/MDCX\n" + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE); + return CMD_SUCCESS; +} + +DEFUN(cfg_mgcp_no_rtp_keepalive, + cfg_mgcp_no_rtp_keepalive_cmd, + "no rtp keep-alive", + NO_STR RTP_STR RTP_KEEPALIVE_STR + ) +{ + mgcp_trunk_set_keepalive(&g_cfg->trunk, 0); + return CMD_SUCCESS; +} + + #define CALL_AGENT_STR "Callagent information\n" DEFUN(cfg_mgcp_agent_addr, @@ -598,6 +640,15 @@ static int config_write_trunk(struct vty *vty) trunk->audio_name, VTY_NEWLINE); vty_out(vty, " %ssdp audio-payload send-ptime%s", trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE); + + if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE) + vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE); + else if (trunk->keepalive_interval) + vty_out(vty, " rtp keep-alive %d%s", + trunk->keepalive_interval, VTY_NEWLINE); + else + vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE); + vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE); if (trunk->omit_rtcp) @@ -780,6 +831,40 @@ DEFUN(cfg_trunk_no_patch_rtp, return CMD_SUCCESS; } +DEFUN(cfg_trunk_rtp_keepalive, + cfg_trunk_rtp_keepalive_cmd, + "rtp keep-alive <1-120>", + RTP_STR RTP_KEEPALIVE_STR + "Keep-alive interval in secs\n" + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_trunk_rtp_keepalive_once, + cfg_trunk_rtp_keepalive_once_cmd, + "rtp keep-alive once", + RTP_STR RTP_KEEPALIVE_STR + "Send dummy packet only once after CRCX/MDCX\n" + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE); + return CMD_SUCCESS; +} + +DEFUN(cfg_trunk_no_rtp_keepalive, + cfg_trunk_no_rtp_keepalive_cmd, + "no rtp keep-alive", + NO_STR RTP_STR RTP_KEEPALIVE_STR + ) +{ + struct mgcp_trunk_config *trunk = vty->index; + mgcp_trunk_set_keepalive(trunk, 0); + return CMD_SUCCESS; +} DEFUN(loop_endp, loop_endp_cmd, @@ -999,6 +1084,9 @@ int mgcp_vty_init(void) install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd); install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd); install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd); + install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd); + install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd); + install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd); install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd); install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old); install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd); @@ -1024,6 +1112,9 @@ int mgcp_vty_init(void) install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd); install_node(&trunk_node, config_write_trunk); vty_install_default(TRUNK_NODE); + install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd); + install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd); + install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd); install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old); diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c index 596ea8a..14ec221 100644 --- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c +++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c @@ -137,15 +137,6 @@ static int mgcp_rsip_cb(struct mgcp_trunk_config *tcfg) return 0; } -static int mgcp_change_cb(struct mgcp_trunk_config *cfg, int endpoint, int state) -{ - if (state != MGCP_ENDP_MDCX) - return 0; - - mgcp_send_dummy(&cfg->endpoints[endpoint]); - return 0; -} - static int read_call_agent(struct osmo_fd *fd, unsigned int what) { struct sockaddr_in addr; @@ -233,7 +224,6 @@ int main(int argc, char **argv) /* set some callbacks */ cfg->reset_cb = mgcp_rsip_cb; - cfg->change_cb = mgcp_change_cb; /* we need to bind a socket */ if (rc == 0) { diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 6db7226..7e8aa5c 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -16,6 +16,7 @@ Testing AUEP2 Testing MDCX1 Testing MDCX2 Testing CRCX +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 1, BTS output enabled, NET output disabled @@ -24,18 +25,22 @@ Packet duration not set Requested packetization period not set Connection mode not set Testing MDCX4 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT1 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-40 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT2 +Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 3, BTS output enabled, NET output enabled Testing MDCX4_PT3 +Dummy packets: 1 Detected packet duration: 40 Requested packetization period not set Connection mode: 3, BTS output enabled, NET output enabled @@ -48,6 +53,7 @@ Detected packet duration: 20 Requested packetization period not set Connection mode: 0, BTS output enabled, NET output enabled Testing CRCX_ZYN +Dummy packets: 1 Packet duration not set Requested packetization period not set Connection mode: 1, BTS output enabled, NET output disabled -- 1.7.9.5 From kheimerl at cs.berkeley.edu Thu Jan 9 04:34:50 2014 From: kheimerl at cs.berkeley.edu (Kurtis Heimerl) Date: Wed, 8 Jan 2014 20:34:50 -0800 Subject: Potential bug in trx_if.c Message-ID: Hey all, I've been working on getting the Range Networks RAD1 working with OsmoBTS. I *think* I've found a bug in trx_if.c. Basically, tsc checks the bsic variable and bsic checks the tsc variable. It *may* be intentional but I doubt that and I wanted to note it before I moved on. Patch is attached. Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index e798ca5..b00523a 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -235,7 +235,7 @@ int trx_if_cmd_settsc(struct trx_l1h *l1h, uint8_t tsc) if (!settsc_enabled) return 0; /* if TSC is enabled only, the positive response is mandatory */ - return trx_ctrl_cmd(l1h, (setbsic_enabled) ? 0 : 1, "SETTSC", "%d", + return trx_ctrl_cmd(l1h, (settsc_enabled) ? 0 : 1, "SETTSC", "%d", tsc); } @@ -244,7 +244,7 @@ int trx_if_cmd_setbsic(struct trx_l1h *l1h, uint8_t bsic) if (!setbsic_enabled) return 0; /* if BSIC is enabled only, the positive response is mandatory */ - return trx_ctrl_cmd(l1h, (settsc_enabled) ? 0 : 1, "SETBSIC", "%d", + return trx_ctrl_cmd(l1h, (setbsic_enabled) ? 0 : 1, "SETBSIC", "%d", bsic); } From andreas at eversberg.eu Thu Jan 9 09:33:56 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 09 Jan 2014 10:33:56 +0100 Subject: Potential bug in trx_if.c In-Reply-To: References: Message-ID: <52CE6D04.30704@eversberg.eu> Kurtis Heimerl wrote: > /* if TSC is enabled only, the positive response is mandatory */ > - return trx_ctrl_cmd(l1h, (setbsic_enabled) ? 0 : 1, "SETTSC", "%d", > hi kurtis, i think this is not a bug. in case we have "SETBSIC" enabled also, we do not require a positive response for SETTSC. (and vice versa). the second parameter of trx_ctrl_cmd() will be 0, which means that we accept a negative response. this is because openbts transceivers require SETTSC (and rejects SETBSIC) and calypso bts hack requires SETBSIC (and rejects SETTSC). regards, andreas From kheimerl at cs.berkeley.edu Thu Jan 9 20:26:07 2014 From: kheimerl at cs.berkeley.edu (Kurtis Heimerl) Date: Thu, 9 Jan 2014 12:26:07 -0800 Subject: OsmoBTS on RAD1 Message-ID: Hey OpenBSC, Tom, I've been working on getting OsmoBTS running on the recently open-sourced Range Networks RAD1 radio. The code is available here: https://github.com/kheimerl/vbts-openbts/tree/osmotrx. I am stuck now and I was hoping the mailing list might be able to provide some perspective. With the RAD1, the system is beaconing correctly. However, phones are unable to camp. I logged a phone trying to camp on both the RAD1 and a B100 to compare the output and see if anything jumps out. The osmoBTS/osmo-nitb logs are seemingly identical, but the transceiver outputs are different. Both of the transceiver outputs are attached. The only big difference I see is in the "underflows" on the RAD1, which in my experience is a deal-breaker; that's not usually an easy fix. Does anyone have a different perspective on what might be going on in here? Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: transceiver-52M.log Type: text/x-log Size: 1253376 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: transceiver-RAD1.log Type: text/x-log Size: 2744320 bytes Desc: not available URL: From tom at tsou.cc Fri Jan 10 11:39:36 2014 From: tom at tsou.cc (Tom Tsou) Date: Fri, 10 Jan 2014 06:39:36 -0500 Subject: OsmoBTS on RAD1 In-Reply-To: References: Message-ID: On Jan 9, 2014 3:26 PM, "Kurtis Heimerl" wrote: > With the RAD1, the system is beaconing correctly. However, phones are unable to camp. I logged a phone trying to camp on both the RAD1 and a B100 to compare the output and see if anything jumps out. The osmoBTS/osmo-nitb logs are seemingly identical, but the transceiver outputs are different. By beaconing correctly, you mean the handset recognize the network? Based on these logs, you're not receiving RACH bursts. Both of the transceiver outputs are attached. The only big difference I see is in the "underflows" on the RAD1, which in my experience is a deal-breaker; that's not usually an easy fix. This is unrelated to osmo-bts. The effect on performance will depend on the frequency of occurrence. -TT -------------- next part -------------- An HTML attachment was scrubbed... URL: From kheimerl at cs.berkeley.edu Sat Jan 11 03:27:17 2014 From: kheimerl at cs.berkeley.edu (Kurtis Heimerl) Date: Fri, 10 Jan 2014 19:27:17 -0800 Subject: OsmoBTS on RAD1 In-Reply-To: References: Message-ID: Thanks for the response! This level is a bit beyond where I normally work. Followup comments in line: On Fri, Jan 10, 2014 at 3:39 AM, Tom Tsou wrote: > On Jan 9, 2014 3:26 PM, "Kurtis Heimerl" wrote: > > With the RAD1, the system is beaconing correctly. However, phones are > unable to camp. I logged a phone trying to camp on both the RAD1 and a B100 > to compare the output and see if anything jumps out. The osmoBTS/osmo-nitb > logs are seemingly identical, but the transceiver outputs are different. > > By beaconing correctly, you mean the handset recognize the network? > Yep. When doing a scan it correctly identifies the new network. > Based on these logs, you're not receiving RACH bursts. > What makes you say that? I don't see RACHs in either log, but the phone camps in the 52M trace so it must have received a RACH. I do see attempts to decode a RACH in the RAD1 trace though... > Both of the transceiver outputs are attached. The only big difference I > see is in the "underflows" on the RAD1, which in my experience is a > deal-breaker; that's not usually an easy fix. > > This is unrelated to osmo-bts. The effect on performance will depend on > the frequency of occurrence. > My thought was that osmo-bts may not be producing enough packets (or something) causing it to underflow. Am I off base there? > -TT > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom at tsou.cc Mon Jan 13 17:39:14 2014 From: tom at tsou.cc (Tom Tsou) Date: Mon, 13 Jan 2014 12:39:14 -0500 Subject: OsmoBTS on RAD1 In-Reply-To: References: Message-ID: On Fri, Jan 10, 2014 at 10:27 PM, Kurtis Heimerl wrote: > Yep. When doing a scan it correctly identifies the new network. > >> Based on these logs, you're not receiving RACH bursts. > > What makes you say that? I don't see RACHs in either log, but the phone > camps in the 52M trace so it must have received a RACH. I do see attempts to > decode a RACH in the RAD1 trace though... The logged RACH burst are below the detection threshold and subsequently dropped - most likely just noise. I assume you're lab testing, so signal strength should not be an issue. If you have logged SDCCH traffic (e.g. L3 registration), then the RACH got through at some point. You may be receiving RACH bursts, but there are no such transactions in the particular posted logs. >> Both of the transceiver outputs are attached. The only big difference I >> see is in the "underflows" on the RAD1, which in my experience is a >> deal-breaker; that's not usually an easy fix. >> >> This is unrelated to osmo-bts. The effect on performance will depend on >> the frequency of occurrence. > > My thought was that osmo-bts may not be producing enough packets (or > something) causing it to underflow. Am I off base there? The sample stream going to the device is continuous in all transceiver cases regardless of what comes down from the upper layers. If osmo-bts or openbts submits less bursts than the other, filler bursts will be added. In other words, from the device I/O standpoint, there should be no difference between osmo-bts and openbts. What happens if you start the transceiver and then shut down core while leaving the transceiver running? Underruns still present? -TT From jerlbeck at sysmocom.de Fri Jan 10 09:41:49 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 10 Jan 2014 10:41:49 +0100 Subject: [PATCH] nitb/vty: Add test for E1 input keep-alive Message-ID: <1389346909-28439-1-git-send-email-jerlbeck@sysmocom.de> This test checks, whether the configuration of e1_line keepalive works. It does not check, whether keep-alive is correctly implemented by the drivers. If the e1_line keepalive command is not provided by the libosmo-abis, this test will be skipped. Sponsored-by: On-Waves ehf --- openbsc/tests/vty_test_runner.py | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 08c94b1..16eb213 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -230,6 +230,61 @@ 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 testE1InputKeepAlive(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("e1_input") + + self.assertEquals(self.vty.node(), 'config-e1_input') + + # Check for keepalive command + res = self.vty.command("list") + if not res.find(' e1_line <0-255> keepalive\r') > 0: + print("Skipping the E1 input keep-alive test") + return + + # Test invalid input + self.vty.verify("e1_line 200 keepalive", ["% Line 200 doesn't exist"]) + self.vty.verify("e1_line 200 keepalive 1", ["% Command incomplete."]) + self.vty.verify("e1_line 200 keepalive 1 2", ["% Command incomplete."]) + self.vty.verify("no e1_line 200 keepalive 1 2 3", ["% Unknown command."]) + + # Setup driver + self.vty.verify("e1_line 201 driver misdn", ['']) + self.vty.verify("e1_line 202 driver misdn_lapd", ['']) + self.vty.verify("e1_line 204 driver ipa", ['']) + + # Test misdn + self.vty.verify("e1_line 201 keepalive", ["% Driver 'misdn' does not support keep alive"]) + res = self.vty.command("write terminal") + self.assert_(res.find("no e1_line 201 keepalive\r") > 0) + + self.vty.verify("no e1_line 201 keepalive", [""]) + + # Test misdn_lapd + self.vty.verify("e1_line 202 keepalive", ["% Driver 'misdn_lapd' does not support keep alive"]) + res = self.vty.command("write terminal") + self.assert_(res.find("no e1_line 202 keepalive\r") > 0) + + self.vty.verify("no e1_line 202 keepalive", [""]) + + # Test ipa + self.vty.verify("e1_line 204 keepalive", [""]) + res = self.vty.command("write terminal") + self.assert_(res.find("e1_line 204 keepalive\r") > 0) + + self.vty.verify("e1_line 204 keepalive 10 1 2", [""]) + res = self.vty.command("write terminal") + self.assert_(res.find("e1_line 204 keepalive 10 1 2\r") > 0) + + self.vty.verify("no e1_line 204 keepalive", [""]) + + # Check whether keep alive is disabled again on each line + res = self.vty.command("write terminal") + self.assert_(res.find("no e1_line 201 keepalive\r") > 0) + self.assert_(res.find("no e1_line 202 keepalive\r") > 0) + self.assert_(res.find("no e1_line 204 keepalive\r") > 0) + class TestVTYBSC(TestVTYGenericBSC): def vty_command(self): -- 1.7.9.5 From andreas at eversberg.eu Fri Jan 10 23:53:21 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 11 Jan 2014 00:53:21 +0100 Subject: Support for Flexi BTS Message-ID: <52D087F1.2050401@eversberg.eu> hi, we managed to run a nokia flexi bts with openbsc. the bts type is "nokia-site". on channel request, the bts nacks the channel activation with cause 0x65 (protocol error, optional information element). by removing the Channel Identification IE from the channel activation message, everything worked, so we assume that this IE causes this error. we tried to modify it: - no zero-length Mobile Allocation included in Channel Identification IE - TLV instead of TV for Channel Description in Channel Identification IE - Channel Description in Channel Identification IE with type 0x62 instead of 0x64 all of these modifications result in the same error. so we came to the conclusion to remove the Channel Identification IE, since it is not really required. attached is the preview patch. does anyone have ABIS traces of a real network, to check how the IE is encoded there? is there any way to get more information from nokia bts why it rejects the channel when using this IE? regards, andreas -------------- next part -------------- A non-text attachment was scrubbed... Name: nokia_no_chan_ident.patch Type: text/x-patch Size: 4902 bytes Desc: not available URL: From laforge at gnumonks.org Sun Jan 12 18:53:26 2014 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 12 Jan 2014 19:53:26 +0100 Subject: [RFC] [ADMIN] Making lists subscriber-only? Message-ID: <20140112185326.GU23594@nataraja> Dear all, so far the osmocom.org mailing lists have always been in a 'non-members are manually moderated' mode. This has created a lot of work for manual list moderation, where a lot of the messages caught are simply spam, and only the occasional valid message is being received. I'd like to thank the list moderators for taking care of this. However, in more recent discussions, we were considering to move the lists to a completely closed mode, i.e. postings would automatically be rejected from non-members. The automatic response would contain a description of how to subscribe in 'nomail' mode, i.e. to subscribe in a way to be able to post to the list, while still not receiving any incoming traffic. The latter should be fine for occasional posters who don't want the bulk e-mail that goes with a full/regular subscription. Please provide feedback in case you disagree with that change. Unless there is major opposition, we will likely transition to the 'closed' mode within one month. Thanks, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 190 bytes Desc: Digital signature URL: From kaber at trash.net Sun Jan 12 19:38:55 2014 From: kaber at trash.net (Patrick McHardy) Date: Sun, 12 Jan 2014 19:38:55 +0000 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: <20140112193855.GB13545@macbook.localnet> On Sun, Jan 12, 2014 at 07:53:26PM +0100, Harald Welte wrote: > Dear all, > > so far the osmocom.org mailing lists have always been in a 'non-members > are manually moderated' mode. This has created a lot of work for manual > list moderation, where a lot of the messages caught are simply spam, and > only the occasional valid message is being received. > > I'd like to thank the list moderators for taking care of this. > > However, in more recent discussions, we were considering to move the > lists to a completely closed mode, i.e. postings would automatically be > rejected from non-members. > > The automatic response would contain a description of how to subscribe > in 'nomail' mode, i.e. to subscribe in a way to be able to post to the > list, while still not receiving any incoming traffic. The latter should > be fine for occasional posters who don't want the bulk e-mail that goes > with a full/regular subscription. > > Please provide feedback in case you disagree with that change. Unless > there is major opposition, we will likely transition to the 'closed' > mode within one month. For the dect list I'm all in favour of this. There's very low traffic and almost only spam. Cheers, Patrick From holger at freyther.de Sun Jan 12 19:55:41 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 12 Jan 2014 20:55:41 +0100 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: <20140112195541.GJ9767@xiaoyu.lan> On Sun, Jan 12, 2014 at 07:53:26PM +0100, Harald Welte wrote: > Dear all, Good Evening, > Please provide feedback in case you disagree with that change. Unless > there is major opposition, we will likely transition to the 'closed' > mode within one month. when I think I make a one time contribution I use the gmane.org service a lot. On some mailinglists the patch/email sent i just dropped and will never arrive at the mailinglist. If we could find a 'closed' but gmane for posting will still work kind of solution that would be super. holger From laforge at gnumonks.org Sun Jan 12 21:25:43 2014 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 12 Jan 2014 22:25:43 +0100 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112195541.GJ9767@xiaoyu.lan> References: <20140112185326.GU23594@nataraja> <20140112195541.GJ9767@xiaoyu.lan> Message-ID: <20140112212543.GW23594@nataraja> Hi Holger, [cutting the Cc list] On Sun, Jan 12, 2014 at 08:55:41PM +0100, Holger Hans Peter Freyther wrote: > If we could find a 'closed' but gmane for posting will still work kind > of solution that would be super. Unfortuntaely mailman only allows white-listing based on from-addresses, and not based on other header fields. What 'From' address will mails posted throguh from gmane.org have? Your regular mail address, I presume :/ Regads, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From nikos.balkanas at eyeonix.com Mon Jan 13 10:12:01 2014 From: nikos.balkanas at eyeonix.com (Nikos Balkanas) Date: Mon, 13 Jan 2014 12:12:01 +0200 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: I, for one, agree totally. Not that i have received *any* spam from this list, but your proposal makes sense. Not that would stop spam, though, they do fake addresses sometimes :-( But because that's how all of the lists, that I know of, work. PS You didn't specify for "personal" feedback, so I am replying to the lists, many of whom I am not a member. Hope it is not considered spam ;-) BR, Nikos On Sun, Jan 12, 2014 at 8:53 PM, Harald Welte wrote: > Dear all, > > so far the osmocom.org mailing lists have always been in a 'non-members > are manually moderated' mode. This has created a lot of work for manual > list moderation, where a lot of the messages caught are simply spam, and > only the occasional valid message is being received. > > I'd like to thank the list moderators for taking care of this. > > However, in more recent discussions, we were considering to move the > lists to a completely closed mode, i.e. postings would automatically be > rejected from non-members. > > The automatic response would contain a description of how to subscribe > in 'nomail' mode, i.e. to subscribe in a way to be able to post to the > list, while still not receiving any incoming traffic. The latter should > be fine for occasional posters who don't want the bulk e-mail that goes > with a full/regular subscription. > > Please provide feedback in case you disagree with that change. Unless > there is major opposition, we will likely transition to the 'closed' > mode within one month. > > Thanks, > Harald > > -- > - Harald Welte > http://laforge.gnumonks.org/ > > ============================================================================ > "Privacy in residential applications is a desirable marketing option." > (ETSI EN 300 175-7 Ch. > A6) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From edoardo.rispoli at gmail.com Mon Jan 13 22:46:47 2014 From: edoardo.rispoli at gmail.com (Edoardo Rispoli) Date: Mon, 13 Jan 2014 23:46:47 +0100 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: ok for the closed mode ! 73 IW3BTI 2014/1/12 Harald Welte > Dear all, > > so far the osmocom.org mailing lists have always been in a 'non-members > are manually moderated' mode. This has created a lot of work for manual > list moderation, where a lot of the messages caught are simply spam, and > only the occasional valid message is being received. > > I'd like to thank the list moderators for taking care of this. > > However, in more recent discussions, we were considering to move the > lists to a completely closed mode, i.e. postings would automatically be > rejected from non-members. > > The automatic response would contain a description of how to subscribe > in 'nomail' mode, i.e. to subscribe in a way to be able to post to the > list, while still not receiving any incoming traffic. The latter should > be fine for occasional posters who don't want the bulk e-mail that goes > with a full/regular subscription. > > Please provide feedback in case you disagree with that change. Unless > there is major opposition, we will likely transition to the 'closed' > mode within one month. > > Thanks, > Harald > > -- > - Harald Welte > http://laforge.gnumonks.org/ > > ============================================================================ > "Privacy in residential applications is a desirable marketing option." > (ETSI EN 300 175-7 Ch. > A6) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From stevie.glass at gmail.com Tue Jan 14 08:21:06 2014 From: stevie.glass at gmail.com (Steve Glass) Date: Tue, 14 Jan 2014 18:21:06 +1000 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: <52D4F372.8010403@gmail.com> Hi Closed lists will just be more efficient. If the bounce message is clear then most genuine contributors will get that and respond appropriately. I've only dealt with one real, actual problem as a moderator and it was purely accidental that the offender wasn't a subscriber and I was able to catch it. We should expect some spammers to join but even this hurdle will eliminate the majority and we can boot any subscribed spammers quite quickly. ATB Stevie From e_tews at seceng.informatik.tu-darmstadt.de Wed Jan 15 08:28:34 2014 From: e_tews at seceng.informatik.tu-darmstadt.de (Erik Tews) Date: Wed, 15 Jan 2014 09:28:34 +0100 Subject: [RFC] [ADMIN] Making lists subscriber-only? In-Reply-To: <20140112185326.GU23594@nataraja> References: <20140112185326.GU23594@nataraja> Message-ID: <1389774514.6112.2.camel@lima> Am Sonntag, den 12.01.2014, 19:53 +0100 schrieb Harald Welte: > Dear all, > > so far the osmocom.org mailing lists have always been in a 'non-members > are manually moderated' mode. This has created a lot of work for manual > list moderation, where a lot of the messages caught are simply spam, and > only the occasional valid message is being received. > > I'd like to thank the list moderators for taking care of this. > > However, in more recent discussions, we were considering to move the > lists to a completely closed mode, i.e. postings would automatically be > rejected from non-members. > > The automatic response would contain a description of how to subscribe > in 'nomail' mode, i.e. to subscribe in a way to be able to post to the > list, while still not receiving any incoming traffic. The latter should > be fine for occasional posters who don't want the bulk e-mail that goes > with a full/regular subscription. > > Please provide feedback in case you disagree with that change. Unless > there is major opposition, we will likely transition to the 'closed' > mode within one month. Hi The only disadvantage I can see is, that you cannot simply CC the list, when you get a question to your personal address, that might be interesting for the list. Your mail will still get through, but the next reply will not make it to the list. But that is quiet acceptable, compared to a lot of spam being send to such lists. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From openbsc-bounces at lists.osmocom.org Mon Jan 13 07:00:14 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Mon, 13 Jan 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: kheimerl at cs.berkeley.edu on Thu Jan 9 21:27:04 2014 Subject: OsmoBTS on RAD1 Cause: Message body is too big: 5402368 bytes with a limit of 400 KB From: kaber at trash.net on Sun Jan 12 20:39:11 2014 Subject: Re: [RFC] [ADMIN] Making lists subscriber-only? Cause: Too many recipients to the message From: holger at freyther.de on Sun Jan 12 20:55:56 2014 Subject: Re: [RFC] [ADMIN] Making lists subscriber-only? Cause: Too many recipients to the message From jerlbeck at sysmocom.de Mon Jan 13 13:21:23 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 13 Jan 2014 14:21:23 +0100 Subject: [PATCH] gsm/gsm48ie: Fix range 256 W[i] decoding Message-ID: <1389619283-29894-1-git-send-email-jerlbeck@sysmocom.de> Currently w[14]/w[15] and w[18]/w[19] are swapped in range 256 format decoding in gsm48_decode_freq_list(). This patch fixes this. Sponsored-by: On-Waves ehf --- src/gsm/gsm48_ie.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gsm/gsm48_ie.c b/src/gsm/gsm48_ie.c index 78619b9..2cc0645 100644 --- a/src/gsm/gsm48_ie.c +++ b/src/gsm/gsm48_ie.c @@ -985,17 +985,17 @@ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, if (len >= 12) w[13] = r->w13; if (len >= 13) - w[14] = r->w15; + w[14] = (r->w14_hi << 2) | r->w14_lo; if (len >= 13) - w[15] = (r->w14_hi << 2) | r->w14_lo; + w[15] = r->w15; if (len >= 14) w[16] = (r->w16_hi << 3) | r->w16_lo; if (len >= 14) w[17] = r->w17; if (len >= 15) - w[18] = r->w19; + w[18] = (r->w18_hi << 3) | r->w18_lo; if (len >= 15) - w[19] = (r->w18_hi << 3) | r->w18_lo; + w[19] = r->w19; if (len >= 16) w[20] = (r->w20_hi << 3) | r->w20_lo; if (len >= 16) -- 1.7.9.5 From openbsc-bounces at lists.osmocom.org Tue Jan 14 07:00:11 2014 From: openbsc-bounces at lists.osmocom.org (openbsc-bounces at lists.osmocom.org) Date: Tue, 14 Jan 2014 08:00:11 +0100 Subject: 1 OpenBSC moderator request(s) waiting Message-ID: The OpenBSC at lists.osmocom.org mailing list has 1 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: edoardo.rispoli at gmail.com on Mon Jan 13 23:46:56 2014 Subject: Re: [RFC] [ADMIN] Making lists subscriber-only? Cause: Post by non-member to a members-only list From andreas at eversberg.eu Tue Jan 14 11:58:11 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 14 Jan 2014 12:58:11 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) Message-ID: <52D52653.3000500@eversberg.eu> hi, while re-basing the osmo-bts-trx code with master, i saw that the ABIS code has been replaced by libosmo-abis. libosmo-abis is not capable of handling multiple RSL connections, so the multi-TRX support is broke now. the attached patch will add multiple RSL connection support to libosmo-abis. regards, andreas -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Support-of-multiple-RSL-connections-for-ABIS-ipacces.patch URL: From jolly at eversberg.eu Tue Jan 14 11:32:35 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Tue, 14 Jan 2014 12:32:35 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) Message-ID: In order to support multiple TRX, multiple RSL connections can be establised. e1inp_ipa_bts_rsl_connect() requires an additional parameter to set the TRX number. The code was tested with osmobts-trx. The user of e1inp_ipa_bts_rsl_connect() (which is osmo-bts) must be upgraded after applying the patch. src/common/oml.c - rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port); + rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port, 0); --- include/osmocom/abis/e1_input.h | 3 ++- src/input/ipaccess.c | 18 +++++++++++------- tests/e1inp_ipa_bts_test.c | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 0abf0b8..2a9890c 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -258,7 +258,8 @@ struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr); /* on an IPA BTS, the BTS needs to establish the RSL connection much * later than the OML connection. */ int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port); + const char *rem_addr, uint16_t rem_port, + uint8_t trx_id); void e1inp_sign_link_destroy(struct e1inp_sign_link *link); int e1inp_line_update(struct e1inp_line *line); diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 9722b2f..20894e4 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -717,7 +717,7 @@ err_line: #define IPA_STRING_MAX 64 static struct msgb * -ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len) +ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len, int trx_nr) { struct msgb *nmsg; char str[IPA_STRING_MAX]; @@ -738,7 +738,7 @@ ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len) switch (data[1]) { case IPAC_IDTAG_UNIT: snprintf(str, sizeof(str), "%u/%u/%u", - dev->site_id, dev->bts_id, dev->trx_id); + dev->site_id, dev->bts_id, trx_nr); break; case IPAC_IDTAG_MACADDR: snprintf(str, sizeof(str), @@ -838,6 +838,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) struct e1inp_sign_link *sign_link; uint8_t *data = msgb_l2(msg); int len = msgb_l2len(msg); + int trx_nr = 0; LOGP(DLINP, LOGL_NOTICE, "received ID get\n"); if (!link->line->ops->sign_link_up) { @@ -847,8 +848,10 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) ret = -EINVAL; goto err; } + if (link->ofd->priv_nr >= E1INP_SIGN_RSL) + trx_nr = link->ofd->priv_nr - E1INP_SIGN_RSL; rmsg = ipa_bts_id_resp(link->line->ops->cfg.ipa.dev, - data + 1, len - 1); + data + 1, len - 1, trx_nr); ret = ipaccess_send(link->ofd->fd, rmsg->data, rmsg->len); if (ret != rmsg->len) { @@ -885,7 +888,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) } else if (link->port == IPA_TCP_PORT_OML) e1i_ts = &link->line->ts[0]; else if (link->port == IPA_TCP_PORT_RSL) - e1i_ts = &link->line->ts[1]; + e1i_ts = &link->line->ts[link->ofd->priv_nr-1]; OSMO_ASSERT(e1i_ts != NULL); @@ -1016,13 +1019,14 @@ static int ipaccess_line_update(struct e1inp_line *line) } int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port) + const char *rem_addr, uint16_t rem_port, + uint8_t trx_id) { struct ipa_client_conn *rsl_link; rsl_link = ipa_client_conn_create(tall_ipa_ctx, - &line->ts[E1INP_SIGN_RSL-1], - E1INP_SIGN_RSL, + &line->ts[E1INP_SIGN_RSL+trx_id-1], + E1INP_SIGN_RSL+trx_id, rem_addr, rem_port, ipaccess_bts_updown_cb, ipaccess_bts_read_cb, diff --git a/tests/e1inp_ipa_bts_test.c b/tests/e1inp_ipa_bts_test.c index 02a4cb3..a43dba3 100644 --- a/tests/e1inp_ipa_bts_test.c +++ b/tests/e1inp_ipa_bts_test.c @@ -70,7 +70,7 @@ sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type) /* Now we can send OML messages to the BSC. */ bts_state = BTS_TEST_OML_SIGN_LINK_UP; } - e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); + e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); break; case E1INP_SIGN_RSL: LOGP(DBTSTEST, LOGL_NOTICE, "RSL link up request received.\n"); -- 1.8.1.5 --------------080608010203010806040100-- From holger at freyther.de Tue Jan 14 16:55:44 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 14 Jan 2014 17:55:44 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <52D52653.3000500@eversberg.eu> References: <52D52653.3000500@eversberg.eu> Message-ID: <20140114165544.GD26608@xiaoyu.lan> On Tue, Jan 14, 2014 at 12:58:11PM +0100, Andreas Eversberg wrote: Good Evening Andreas, > The code was tested with osmobts-trx. What does that it mean? What was the result of the test? What was the content of the test. "I tested it" is a sentence without any content. ;) > The user of e1inp_ipa_bts_rsl_connect() (which is osmo-bts) must be > upgraded after applying the patch. okay. thanks for the patch. > - dev->site_id, dev->bts_id, dev->trx_id); > + dev->site_id, dev->bts_id, trx_nr); We have an inconsistency problem here. From a design point of view it is bad to have dev->trx_id and a way to pass in the trx_nr. We can't remove dev->trx_id as OpenBSC is using it. Why can't we have more than one instance of the ipaccess_unit structure? For the sysmoBTS 2050 the mac addresses might/will be different too. > + if (link->ofd->priv_nr >= E1INP_SIGN_RSL) > + trx_nr = link->ofd->priv_nr - E1INP_SIGN_RSL; > + e1i_ts = &link->line->ts[link->ofd->priv_nr-1]; Where does this difference come from? What are the alternatives to this patch? Can we copy the cfg.ipa fields into a per RSL line field and set the trx_id there before the first time we use it? holger From andreas at eversberg.eu Wed Jan 15 09:09:16 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 15 Jan 2014 10:09:16 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <20140114165544.GD26608@xiaoyu.lan> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> Message-ID: <52D6503C.3010305@eversberg.eu> Holger Hans Peter Freyther wrote: hi holger, > What does that it mean? What was the result of the test? What was > the content of the test. "I tested it" is a sentence without any > content. ;) i setup a UmTRX with two transceivers and used the jolly/trx_rebased branch to develop and test this patch. then i made calls on timeslots of different TRX, to see if the correct RSL connection is used to handle the channel. RSL connections on both TRX worked. >> + if (link->ofd->priv_nr >= E1INP_SIGN_RSL) >> + trx_nr = link->ofd->priv_nr - E1INP_SIGN_RSL; >> >> + e1i_ts = &link->line->ts[link->ofd->priv_nr-1]; >> > Where does this difference come from? > the priv_nr is set to E1INP_SIGN_OML (1) or E1INP_SIGN_RSL+trx_nr (2..). in order to retrieve the trx_nr from priv_nr, i substract E1INP_SIGN_RSL. the priv_nr is also the index for selecting the ts structure. because we do not have a physical E1 line, we can use ts[0] also, so '1' is substracted. > What are the alternatives to this patch? Can we copy the cfg.ipa fields > into a per RSL line field and set the trx_id there before the first time > we use it? > i looked at the data structure. the ipaccess_unit structure, which is linked to cfg.ipa.dev could be removed. instead we could provide individual ipaccess_unit structure per RSL/OML link. when calling e1inp_ipa_bts_rsl_connect(), we could provide a pointer to the individual structure. this pointer must be stored inside ipa_client_conn structure then. alternatively we could provide an array of ipaccess_unit, instead of a single structure and attach it to cfg.ipa.dev. in both cases, the BTS code must care of filling the ipaccess_unit structures with data for OML and each RSL link. regards, andreas From holger at freyther.de Mon Jan 20 07:33:27 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 08:33:27 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <52D6503C.3010305@eversberg.eu> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> Message-ID: <20140120073327.GF27930@xiaoyu.lan> On Wed, Jan 15, 2014 at 10:09:16AM +0100, Andreas Eversberg wrote: > alternatively we could provide an array of ipaccess_unit, instead of a > single structure and attach it to cfg.ipa.dev. > > in both cases, the BTS code must care of filling the ipaccess_unit > structures with data for OML and each RSL link. please do that. From andreas at eversberg.eu Mon Jan 20 14:12:00 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 20 Jan 2014 15:12:00 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <20140120073327.GF27930@xiaoyu.lan> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> Message-ID: <52DD2EB0.6010309@eversberg.eu> dear holger, i change the patch. also i attached the change that is required for osmo-bts (sysmobts) to work afterwards. best regards, andreas From jolly at eversberg.eu Tue Jan 14 11:32:35 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Tue, 14 Jan 2014 12:32:35 +0100 Subject: [PATCH] Support for multiple RSL connections with ABIS/ipaccess (BTS side) Message-ID: In order to support multiple TRX, multiple RSL connections can be establised. e1inp_ipa_bts_rsl_connect() requires an additional parameter to set the TRX number. The code was successfully tested with osmobts-trx and UmTRX with two transceivers. The user of e1inp_ipa_bts_rsl_connect() and e1inp_line_bind_ops() (which is osmo-bts) must be upgraded after applying the patch. --- include/osmocom/abis/e1_input.h | 3 ++- src/input/ipaccess.c | 16 ++++++++++------ tests/e1inp_ipa_bts_test.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 0abf0b8..2a9890c 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -258,7 +258,8 @@ struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr); /* on an IPA BTS, the BTS needs to establish the RSL connection much * later than the OML connection. */ int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port); + const char *rem_addr, uint16_t rem_port, + uint8_t trx_id); void e1inp_sign_link_destroy(struct e1inp_sign_link *link); int e1inp_line_update(struct e1inp_line *line); diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 9722b2f..86ddd3a 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -838,6 +838,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) struct e1inp_sign_link *sign_link; uint8_t *data = msgb_l2(msg); int len = msgb_l2len(msg); + struct ipaccess_unit *unit_data; LOGP(DLINP, LOGL_NOTICE, "received ID get\n"); if (!link->line->ops->sign_link_up) { @@ -847,7 +848,9 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) ret = -EINVAL; goto err; } - rmsg = ipa_bts_id_resp(link->line->ops->cfg.ipa.dev, + unit_data = (struct ipaccess_unit *) + link->line->ops->cfg.ipa.dev; + rmsg = ipa_bts_id_resp(&unit_data[link->ofd->priv_nr-1], data + 1, len - 1); ret = ipaccess_send(link->ofd->fd, rmsg->data, rmsg->len); @@ -869,7 +872,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) } msgb_free(rmsg); - sign_link = link->line->ops->sign_link_up(msg, + sign_link = link->line->ops->sign_link_up(unit_data, link->line, link->ofd->priv_nr); if (sign_link == NULL) { @@ -885,7 +888,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) } else if (link->port == IPA_TCP_PORT_OML) e1i_ts = &link->line->ts[0]; else if (link->port == IPA_TCP_PORT_RSL) - e1i_ts = &link->line->ts[1]; + e1i_ts = &link->line->ts[link->ofd->priv_nr-1]; OSMO_ASSERT(e1i_ts != NULL); @@ -1016,13 +1019,14 @@ static int ipaccess_line_update(struct e1inp_line *line) } int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port) + const char *rem_addr, uint16_t rem_port, + uint8_t trx_id) { struct ipa_client_conn *rsl_link; rsl_link = ipa_client_conn_create(tall_ipa_ctx, - &line->ts[E1INP_SIGN_RSL-1], - E1INP_SIGN_RSL, + &line->ts[E1INP_SIGN_RSL+trx_id-1], + E1INP_SIGN_RSL+trx_id, rem_addr, rem_port, ipaccess_bts_updown_cb, ipaccess_bts_read_cb, diff --git a/tests/e1inp_ipa_bts_test.c b/tests/e1inp_ipa_bts_test.c index 02a4cb3..a43dba3 100644 --- a/tests/e1inp_ipa_bts_test.c +++ b/tests/e1inp_ipa_bts_test.c @@ -70,7 +70,7 @@ sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type) /* Now we can send OML messages to the BSC. */ bts_state = BTS_TEST_OML_SIGN_LINK_UP; } - e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); + e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); break; case E1INP_SIGN_RSL: LOGP(DBTSTEST, LOGL_NOTICE, "RSL link up request received.\n"); -- 1.8.1.5 --------------030007020209040104000503 Content-Type: text/x-diff; name="osmo-bts_Support-for-multiple-RSL-connections.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="osmo-bts_Support-for-multiple-RSL-connections.patch" From jolly at eversberg.eu Mon Jan 20 12:08:21 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Mon, 20 Jan 2014 13:08:21 +0100 Subject: [PATCH] ABIS: Support for multiple RSL connections Message-ID: --- include/osmo-bts/abis.h | 2 +- src/common/abis.c | 57 ++++++++++++++++++++++++++++++++++------------- src/common/oml.c | 7 +++--- src/osmo-bts-sysmo/main.c | 2 +- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/include/osmo-bts/abis.h b/include/osmo-bts/abis.h index fb0fbd7..ceda736 100644 --- a/include/osmo-bts/abis.h +++ b/include/osmo-bts/abis.h @@ -17,7 +17,7 @@ enum { }; struct e1inp_line *abis_open(struct gsm_bts *bts, const char *dst_host, - const char *model_name); + const char *model_name, int num_trx); int abis_oml_sendmsg(struct msgb *msg); diff --git a/src/common/abis.c b/src/common/abis.c index 37e82f3..4c4699d 100644 --- a/src/common/abis.c +++ b/src/common/abis.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,8 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type) { struct e1inp_sign_link *sign_link = NULL; + struct gsm_bts_trx *trx; + uint8_t trx_id; switch (type) { case E1INP_SIGN_OML: @@ -79,17 +82,22 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, sign_link->trx = g_bts->c0; bts_link_estab(g_bts); break; - case E1INP_SIGN_RSL: - LOGP(DABIS, LOGL_INFO, "RSL Signalling link up\n"); - e1inp_ts_config_sign(&line->ts[E1INP_SIGN_RSL-1], line); - sign_link = g_bts->c0->rsl_link = - e1inp_sign_link_create(&line->ts[E1INP_SIGN_RSL-1], - E1INP_SIGN_RSL, NULL, 0, 0); - /* FIXME: This assumes there is only one TRX! */ - sign_link->trx = g_bts->c0; - trx_link_estab(sign_link->trx); - break; default: + trx_id = type - E1INP_SIGN_RSL; + LOGP(DABIS, LOGL_INFO, "RSL Signalling link for TRX %d up\n", + trx_id); + trx = gsm_bts_trx_num(g_bts, trx_id); + if (!trx) { + LOGP(DABIS, LOGL_ERROR, "TRX ID %d does not exits\n", + trx_id); + break; + } + e1inp_ts_config_sign(&line->ts[type-1], line); + sign_link = trx->rsl_link = + e1inp_sign_link_create(&line->ts[type-1], + E1INP_SIGN_RSL, NULL, 0, 0); + sign_link->trx = trx; + trx_link_estab(trx); break; } @@ -98,12 +106,16 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, static void sign_link_down(struct e1inp_line *line) { + struct gsm_bts_trx *trx; + LOGP(DABIS, LOGL_ERROR, "Signalling link down\n"); - if (g_bts->c0->rsl_link) { - e1inp_sign_link_destroy(g_bts->c0->rsl_link); - g_bts->c0->rsl_link = NULL; - trx_link_estab(g_bts->c0); + llist_for_each_entry(trx, &g_bts->trx_list, list) { + if (trx->rsl_link) { + e1inp_sign_link_destroy(trx->rsl_link); + trx->rsl_link = NULL; + trx_link_estab(trx); + } } if (g_bts->oml_link) @@ -212,7 +224,6 @@ static struct e1inp_line_ops line_ops = { .cfg = { .ipa = { .role = E1INP_LINE_R_BTS, - .dev = &bts_dev_info, }, }, .sign_link_up = sign_link_up, @@ -224,9 +235,11 @@ static struct e1inp_line_ops line_ops = { * global initialization as well as the actual opening of the A-bis link * */ struct e1inp_line *abis_open(struct gsm_bts *bts, const char *dst_host, - const char *model_name) + const char *model_name, int num_trx) { struct e1inp_line *line; + struct ipaccess_unit *units; + int i; g_bts = bts; @@ -236,6 +249,13 @@ struct e1inp_line *abis_open(struct gsm_bts *bts, const char *dst_host, osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts); + /* allocate list of ipaccess dev info (OML and each RSL connection) */ + units = talloc_zero_array(tall_bts_ctx, struct ipaccess_unit, + num_trx+1); + if (!units) + return NULL; + line_ops.cfg.ipa.dev = units; + /* patch in various data from VTY and othe sources */ line_ops.cfg.ipa.addr = dst_host; get_mac_addr("eth0", bts_dev_info.mac_addr); @@ -250,6 +270,11 @@ struct e1inp_line *abis_open(struct gsm_bts *bts, const char *dst_host, if (!line) return NULL; e1inp_line_bind_ops(line, &line_ops); + memcpy(&units[0], &bts_dev_info, sizeof(*units)); + for (i = 0; i < num_trx; i++) { + memcpy(&units[i+1], &bts_dev_info, sizeof(*units)); + units[i+1].trx_id = i; + } /* This is what currently starts both the outbound OML and RSL * connections, which is wrong. diff --git a/src/common/oml.c b/src/common/oml.c index bf174b5..acde230 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -1018,10 +1018,11 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg, } in.s_addr = htonl(ip); - LOGP(DOML, LOGL_INFO, "Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x\n", - inet_ntoa(in), port, stream_id); + LOGP(DOML, LOGL_INFO, "Rx IPA RSL CONNECT TRX=%d IP=%s PORT=%u " + "STREAM=0x%02x\n", trx->nr, inet_ntoa(in), port, stream_id); - rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port); + rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port, + trx->nr); if (rc < 0) { LOGP(DOML, LOGL_ERROR, "Error in abis_open(RSL): %d\n", rc); return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 74ee47f..f85748f 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -365,7 +365,7 @@ int main(int argc, char **argv) exit(1); } - line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS"); + line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS", 1); if (!line) { fprintf(stderr, "unable to connect to BSC\n"); exit(1); -- 1.8.1.5 --------------030007020209040104000503-- From holger at freyther.de Mon Jan 20 13:28:06 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 14:28:06 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <52DD2EB0.6010309@eversberg.eu> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> Message-ID: <20140120132806.GJ27930@xiaoyu.lan> On Mon, Jan 20, 2014 at 03:12:00PM +0100, Andreas Eversberg wrote: > dear holger, > > i change the patch. also i attached the change that is required for > osmo-bts (sysmobts) to work afterwards. hmm, I might not understand what your patch does but the trx_id is still in more than a single place. Make the ipaccess_unit the primary holder of the trx_id. > - e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); > + e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); > - line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS"); > + line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS", 1); Why do you start with trx_id == 1 in the BTS part but in the manual case with 0? From andreas at eversberg.eu Mon Jan 20 19:04:22 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 20 Jan 2014 20:04:22 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <20140120132806.GJ27930@xiaoyu.lan> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> <20140120132806.GJ27930@xiaoyu.lan> Message-ID: <52DD7336.6010900@eversberg.eu> Holger Hans Peter Freyther wrote: > hmm, I might not understand what your patch does but the trx_id is > still in more than a single place. Make the ipaccess_unit the primary > holder of the trx_id. in my last patch (for osmo-bts), the trx_id is set in each entry of an array of ipaccess_unit structure. the first entry is used for OML link, trx_id is not used there, so it is set to 0. the second (and subsequent) array entry is used for RSL. there the trx_id is set to the TRX number, starting with 0. (sysmobts only uses one TRX.) >> >- e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); >> >+ e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); >> >- line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS"); >> >+ line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS", 1); > Why do you start with trx_id == 1 in the BTS part but in the manual > case with 0? the abis_open() function gets the number of TRX to be used, not the trx_id. as shown above, the abis_open shall create the OML link and 1 RSL link for 1 TRX. the e1inp_ip_bts_rsl_connect() function, as shown above, gets the parameter 0, which means it should connect the first RSL link, which uses trx_id 0. From holger at freyther.de Mon Jan 20 19:00:12 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 20:00:12 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <52DD7336.6010900@eversberg.eu> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> <20140120132806.GJ27930@xiaoyu.lan> <52DD7336.6010900@eversberg.eu> Message-ID: <20140120190012.GS27930@xiaoyu.lan> On Mon, Jan 20, 2014 at 08:04:22PM +0100, Andreas Eversberg wrote: Dear Andreas, my initial comment was that information should be at a single place. The reason is that due bitrot/misc/etc. can change and one might think one talks about the same thing when in fact one doesn't. In the spirit of avoiding broken windows we have to avoid such inconsistencies when they come up. > in my last patch (for osmo-bts), the trx_id is set in each entry of > an array of ipaccess_unit structure. the first entry is used for OML > link, trx_id is not used there, so it is set to 0. the second (and > subsequent) array entry is used for RSL. there the trx_id is set to > the TRX number, starting with 0. (sysmobts only uses one TRX.) > >>>- e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); > >>>+ e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); > >>>- line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS"); > >>>+ line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS", 1); > >Why do you start with trx_id == 1 in the BTS part but in the manual > >case with 0? > the abis_open() function gets the number of TRX to be used, not the > trx_id. as shown above, the abis_open shall create the OML link and > 1 RSL link for 1 TRX. > the e1inp_ip_bts_rsl_connect() function, as shown above, gets the > parameter 0, which means it should connect the first RSL link, which > uses trx_id 0. With your patch there is: * trx->nr * trx_id in the parameters * trx_id in the ipaccess_unit So how can we reduce the amount of duplication? trx->nr will not go away. Can we change e1inp_ipa_bts_rsl_connect to already work on a sign_link (that normally would be created more late, probably not)? any ideas? holger From andreas at eversberg.eu Tue Jan 21 10:19:17 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 21 Jan 2014 11:19:17 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <20140120190012.GS27930@xiaoyu.lan> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> <20140120132806.GJ27930@xiaoyu.lan> <52DD7336.6010900@eversberg.eu> <20140120190012.GS27930@xiaoyu.lan> Message-ID: <52DE49A5.7080700@eversberg.eu> Holger Hans Peter Freyther wrote: > th your patch there is: > > * trx->nr > * trx_id in the parameters > * trx_id in the ipaccess_unit > > So how can we reduce the amount of duplication? trx->nr will not go > away. Can we change e1inp_ipa_bts_rsl_connect to already work on a > sign_link (that normally would be created more late, probably not)? dear holger, i looked at the code again. my thoughts are: the trx_id in the parameters (that is e1inp_ipa_bts_rsl_connect) should be renamed to "index". that is what the parameter is used for: the index of the RSL link instance. we could provide sign_link instead of some index, but inside e1inp_ipa_bts_rsl_connect we call ipa_client_conn_create, which also requires an index. (this index is stored at priv_nr of the osmo_fd, to resolve ABIS link when receiving data.) the trx_id in the ipaccess_unit is something that is replied to the BSC, to identify the TRX. there should be no relation between the value of trx_id and the actual RSL link instance. this makes sense, if multiple devices provide different TRX for the same BTS. (e.g. first device provides two TRX with trx_id 0 and 1, and second device provides two additional TRX with trx_id 2 and 3. both devices have only two RSL link instances.) best regards, andreass From holger at freyther.de Tue Jan 21 09:54:35 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 21 Jan 2014 10:54:35 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <52DE49A5.7080700@eversberg.eu> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> <20140120132806.GJ27930@xiaoyu.lan> <52DD7336.6010900@eversberg.eu> <20140120190012.GS27930@xiaoyu.lan> <52DE49A5.7080700@eversberg.eu> Message-ID: <20140121095435.GW27930@xiaoyu.lan> On Tue, Jan 21, 2014 at 11:19:17AM +0100, Andreas Eversberg wrote: dear andreas, > i looked at the code again. my thoughts are: > > the trx_id in the parameters (that is e1inp_ipa_bts_rsl_connect) > should be renamed to "index". that is what the parameter is used > for: the index of the RSL link instance. we could provide sign_link > instead of some index, but inside e1inp_ipa_bts_rsl_connect we call > ipa_client_conn_create, which also requires an index. (this index is > stored at priv_nr of the osmo_fd, to resolve ABIS link when > receiving data.) thanks a lot. I went through the code as well and I think the first version you sent is better than the second one. On the first version what I am missing is some documentation on how we segment the TS array for OML/RSL and a range check for the trx/index. Do you think you could add this to the first patch? thanks holger From andreas at eversberg.eu Tue Jan 21 15:17:54 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 21 Jan 2014 16:17:54 +0100 Subject: [PATCH] Support of multiple RSL connections for ABIS/ipaccess (BTS side) In-Reply-To: <20140121095435.GW27930@xiaoyu.lan> References: <52D52653.3000500@eversberg.eu> <20140114165544.GD26608@xiaoyu.lan> <52D6503C.3010305@eversberg.eu> <20140120073327.GF27930@xiaoyu.lan> <52DD2EB0.6010309@eversberg.eu> <20140120132806.GJ27930@xiaoyu.lan> <52DD7336.6010900@eversberg.eu> <20140120190012.GS27930@xiaoyu.lan> <52DE49A5.7080700@eversberg.eu> <20140121095435.GW27930@xiaoyu.lan> Message-ID: <52DE8FA2.2020402@eversberg.eu> Holger Hans Peter Freyther wrote: > thanks a lot. I went through the code as well and I think the first > version you sent is better than the second one. On the first version > what I am missing is some documentation on how we segment the TS > array for OML/RSL and a range check for the trx/index. Do you think > you could add this to the first patch? dear holger, see attachment. best regards, andreas From jolly at eversberg.eu Tue Jan 21 13:54:41 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Tue, 21 Jan 2014 14:54:41 +0100 Subject: [PATCH] Support for multiple RSL connections with ABIS/ipaccess (BTS side) Message-ID: In order to support multiple TRX, multiple RSL connections can be establised. e1inp_ipa_bts_rsl_connect() requires an additional parameter to set the TRX number. The ts[] array (member of struct e1inp_line) refers to OML and RSL. ts[0] refers to OML link, ts[1] to RSL link of first TRX, ts[2] to RSL link of second TRX (if exists) and so on. The code was successfully tested with osmobts-trx and UmTRX with two transceivers. The user of e1inp_ipa_bts_rsl_connect() (which is osmo-bts) must be upgraded after applying the patch. src/common/oml.c - rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port); + rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port, + trx->nr); --- include/osmocom/abis/e1_input.h | 3 ++- src/input/ipaccess.c | 30 +++++++++++++++++++++++------- tests/e1inp_ipa_bts_test.c | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 9b77893..7fbffe9 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -265,7 +265,8 @@ struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr); /* on an IPA BTS, the BTS needs to establish the RSL connection much * later than the OML connection. */ int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port); + const char *rem_addr, uint16_t rem_port, + uint8_t trx_id); void e1inp_sign_link_destroy(struct e1inp_sign_link *link); int e1inp_line_update(struct e1inp_line *line); diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index 07b47b2..4091d09 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -774,7 +774,7 @@ err_line: #define IPA_STRING_MAX 64 static struct msgb * -ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len) +ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len, int trx_nr) { struct msgb *nmsg; char str[IPA_STRING_MAX]; @@ -795,7 +795,7 @@ ipa_bts_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len) switch (data[1]) { case IPAC_IDTAG_UNIT: snprintf(str, sizeof(str), "%u/%u/%u", - dev->site_id, dev->bts_id, dev->trx_id); + dev->site_id, dev->bts_id, trx_nr); break; case IPAC_IDTAG_MACADDR: snprintf(str, sizeof(str), @@ -895,6 +895,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) struct e1inp_sign_link *sign_link; uint8_t *data = msgb_l2(msg); int len = msgb_l2len(msg); + int trx_nr = 0; LOGP(DLINP, LOGL_NOTICE, "received ID get\n"); if (!link->line->ops->sign_link_up) { @@ -904,8 +905,10 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) ret = -EINVAL; goto err; } + if (link->ofd->priv_nr >= E1INP_SIGN_RSL) + trx_nr = link->ofd->priv_nr - E1INP_SIGN_RSL; rmsg = ipa_bts_id_resp(link->line->ops->cfg.ipa.dev, - data + 1, len - 1); + data + 1, len - 1, trx_nr); ret = ipaccess_send(link->ofd->fd, rmsg->data, rmsg->len); if (ret != rmsg->len) { @@ -942,7 +945,7 @@ static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) } else if (link->port == IPA_TCP_PORT_OML) e1i_ts = &link->line->ts[0]; else if (link->port == IPA_TCP_PORT_RSL) - e1i_ts = &link->line->ts[1]; + e1i_ts = &link->line->ts[link->ofd->priv_nr-1]; OSMO_ASSERT(e1i_ts != NULL); @@ -1073,13 +1076,26 @@ static int ipaccess_line_update(struct e1inp_line *line) } int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line, - const char *rem_addr, uint16_t rem_port) + const char *rem_addr, uint16_t rem_port, + uint8_t trx_nr) { struct ipa_client_conn *rsl_link; + if (E1INP_SIGN_RSL+trx_nr-1 >= NUM_E1_TS) { + LOGP(DLINP, LOGL_ERROR, "cannot create RSL BTS link: " + "trx_nr (%d) out of range\n", trx_nr); + return -EINVAL; + } + if (line->ts[E1INP_SIGN_RSL+trx_nr-1].type != E1INP_TS_TYPE_SIGN) { + LOGP(DLINP, LOGL_ERROR, "cannot create RSL BTS link: " + "trx_nr (%d) does not refer to a signalling link\n", + trx_nr); + return -EINVAL; + } + rsl_link = ipa_client_conn_create(tall_ipa_ctx, - &line->ts[E1INP_SIGN_RSL-1], - E1INP_SIGN_RSL, + &line->ts[E1INP_SIGN_RSL+trx_nr-1], + E1INP_SIGN_RSL+trx_nr, rem_addr, rem_port, ipaccess_bts_updown_cb, ipaccess_bts_read_cb, diff --git a/tests/e1inp_ipa_bts_test.c b/tests/e1inp_ipa_bts_test.c index 02a4cb3..a43dba3 100644 --- a/tests/e1inp_ipa_bts_test.c +++ b/tests/e1inp_ipa_bts_test.c @@ -70,7 +70,7 @@ sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type) /* Now we can send OML messages to the BSC. */ bts_state = BTS_TEST_OML_SIGN_LINK_UP; } - e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL); + e1inp_ipa_bts_rsl_connect(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0); break; case E1INP_SIGN_RSL: LOGP(DBTSTEST, LOGL_NOTICE, "RSL link up request received.\n"); -- 1.8.1.5 --------------050208090707040108050104-- From jerlbeck at sysmocom.de Tue Jan 14 13:24:15 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:15 +0100 Subject: [PATCH 1/9] si: Add a hack to disable SI2ter/SI2bis/SI5ter/SI5bis messages Message-ID: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> From: Holger Hans Peter Freyther The iPhone5 (US) appears to have some issues with the SIs generated, or the nanoBTS is not sending them correctly. Add a hack to put all bands into the SI2/SI5 message. This is a quick change without much reflection and watching for side effects. I have verfied that a network with ARFCN 134 and neighbors ARFCN 130 and 512 do not get generate the SI2ter and announce everything inside the SI2. --- openbsc/src/libbsc/system_information.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index c901a4a..cb67011 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -44,6 +44,7 @@ * array. DCS1800 and PCS1900 can not be used at the same time so conserve * memory and do the below. */ +#if 0 static int band_compatible(const struct gsm_bts *bts, int arfcn) { enum gsm_band band = gsm_arfcn2band(arfcn); @@ -57,6 +58,7 @@ static int band_compatible(const struct gsm_bts *bts, int arfcn) return 0; } +#endif static int is_dcs_net(const struct gsm_bts *bts) { @@ -70,6 +72,11 @@ static int is_dcs_net(const struct gsm_bts *bts) static int use_arfcn(const struct gsm_bts *bts, const int bis, const int ter, const int pgsm, const int arfcn) { + if (bis || ter) + return 0; + return 1; +#if 0 + Correct but somehow broken with either the nanoBTS or the iPhone5 if (!bis && !ter && band_compatible(bts, arfcn)) return 1; if (bis && pgsm && band_compatible(bts, arfcn) && (arfcn < 1 || arfcn > 124)) @@ -77,6 +84,7 @@ static int use_arfcn(const struct gsm_bts *bts, const int bis, const int ter, if (ter && !band_compatible(bts, arfcn)) return 1; return 0; +#endif } /* Frequency Lists as per TS 04.08 10.5.2.13 */ -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:16 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:16 +0100 Subject: [PATCH 2/9] si: Make disabling SI2ter/SI2bis/SI5ter/SI5bis configurable In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-2-git-send-email-jerlbeck@sysmocom.de> Currently the generation of SI2ter/SI2bis/SI5ter/SI5bis is always disabled (see former patch 'si: Add a hack to disable SI2ter/SI2bis/SI5ter/SI5bis messages'). This patch turns the hack into a configuration option, enabled by the bts VTY command 'force-combined-si'. Ticket: OW#1062 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gsm_data_shared.h | 3 +++ openbsc/src/libbsc/bsc_vty.c | 27 +++++++++++++++++++++++++++ openbsc/src/libbsc/system_information.c | 11 +++-------- openbsc/tests/vty_test_runner.py | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index b49a539..0922f78 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -670,6 +670,9 @@ struct gsm_bts { int num_trx; struct llist_head trx_list; + /* SI compatibility hacks */ + int force_combined_si; + #ifdef ROLE_BSC /* Abis NM queue */ struct llist_head abis_queue; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 7fa5ea7..4d09e15 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -636,6 +636,9 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) if (bts->excl_from_rf_lock) vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE); + vty_out(vty, " %sforce-combined-si%s", + bts->force_combined_si ? "" : "no ", VTY_NEWLINE); + config_write_bts_model(vty, bts); } @@ -2658,6 +2661,28 @@ DEFUN(cfg_bts_no_excl_rf_lock, return CMD_SUCCESS; } +#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n" + +DEFUN(cfg_bts_force_comb_si, + cfg_bts_force_comb_si_cmd, + "force-combined-si", + FORCE_COMB_SI_STR) +{ + struct gsm_bts *bts = vty->index; + bts->force_combined_si = 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_force_comb_si, + cfg_bts_no_force_comb_si_cmd, + "no force-combined-si", + NO_STR FORCE_COMB_SI_STR) +{ + struct gsm_bts *bts = vty->index; + bts->force_combined_si = 0; + return CMD_SUCCESS; +} + #define TRX_TEXT "Radio Transceiver\n" /* per TRX configuration */ @@ -3255,6 +3280,8 @@ int bsc_vty_init(const struct log_info *cat) install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd); install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd); install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd); + install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd); + install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd); install_element(BTS_NODE, &cfg_trx_cmd); install_node(&trx_node, dummy_config_write); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index cb67011..5f46bf9 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -44,7 +44,6 @@ * array. DCS1800 and PCS1900 can not be used at the same time so conserve * memory and do the below. */ -#if 0 static int band_compatible(const struct gsm_bts *bts, int arfcn) { enum gsm_band band = gsm_arfcn2band(arfcn); @@ -58,7 +57,6 @@ static int band_compatible(const struct gsm_bts *bts, int arfcn) return 0; } -#endif static int is_dcs_net(const struct gsm_bts *bts) { @@ -72,19 +70,16 @@ static int is_dcs_net(const struct gsm_bts *bts) static int use_arfcn(const struct gsm_bts *bts, const int bis, const int ter, const int pgsm, const int arfcn) { - if (bis || ter) - return 0; - return 1; -#if 0 - Correct but somehow broken with either the nanoBTS or the iPhone5 if (!bis && !ter && band_compatible(bts, arfcn)) return 1; + if (bts->force_combined_si) + return 0; + /* Correct but somehow broken with either the nanoBTS or the iPhone5 */ if (bis && pgsm && band_compatible(bts, arfcn) && (arfcn < 1 || arfcn > 124)) return 1; if (ter && !band_compatible(bts, arfcn)) return 1; return 0; -#endif } /* Frequency Lists as per TS 04.08 10.5.2.13 */ diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 16eb213..47e1ad1 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -173,6 +173,24 @@ class TestVTYNITB(TestVTYGenericBSC): self.assertEquals(res.find('periodic location update 60'), -1) self.assert_(res.find('no periodic location update') > 0) + def testEnableDisableSiHacks(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("network") + self.vty.command("bts 0") + + # Enable periodic lu.. + self.vty.verify("force-combined-si", ['']) + res = self.vty.command("write terminal") + self.assert_(res.find(' force-combined-si') > 0) + self.assertEquals(res.find('no force-combined-si'), -1) + + # Now disable it.. + self.vty.verify("no force-combined-si", ['']) + res = self.vty.command("write terminal") + self.assertEquals(res.find(' force-combined-si'), -1) + self.assert_(res.find('no force-combined-si') > 0) + def testRachAccessControlClass(self): self.vty.enable() self.vty.command("configure terminal") -- 1.7.9.5 From holger at freyther.de Tue Jan 14 16:31:45 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 14 Jan 2014 17:31:45 +0100 Subject: [PATCH 2/9] si: Make disabling SI2ter/SI2bis/SI5ter/SI5bis configurable In-Reply-To: <1389705863-3730-2-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389705863-3730-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140114163145.GB26608@xiaoyu.lan> On Tue, Jan 14, 2014 at 02:24:16PM +0100, Jacob Erlbeck wrote: > Currently the generation of SI2ter/SI2bis/SI5ter/SI5bis is always > disabled (see former patch 'si: Add a hack to disable > SI2ter/SI2bis/SI5ter/SI5bis messages'). I would like to squash 1/2. For later bi-section it makes sense to not disable a feature in just one commit. From jerlbeck at sysmocom.de Wed Jan 15 13:11:18 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:11:18 +0100 Subject: [PATCH 2/9] si: Make disabling SI2ter/SI2bis/SI5ter/SI5bis configurable In-Reply-To: <20140114163145.GB26608@xiaoyu.lan> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389705863-3730-2-git-send-email-jerlbeck@sysmocom.de> <20140114163145.GB26608@xiaoyu.lan> Message-ID: <52D688F6.2030106@sysmocom.de> On 14.01.2014 17:31, Holger Hans Peter Freyther wrote: > On Tue, Jan 14, 2014 at 02:24:16PM +0100, Jacob Erlbeck wrote: >> Currently the generation of SI2ter/SI2bis/SI5ter/SI5bis is always >> disabled (see former patch 'si: Add a hack to disable >> SI2ter/SI2bis/SI5ter/SI5bis messages'). > > I would like to squash 1/2. For later bi-section it makes sense to > not disable a feature in just one commit. > Ok, I'll squash it. From jerlbeck at sysmocom.de Tue Jan 14 13:24:17 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:17 +0100 Subject: [PATCH 3/9] si: Use range 512 encoding format whenever possible In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-3-git-send-email-jerlbeck@sysmocom.de> The current code only implements the bit packing for the range 512 encoding format. This patch prefers the (implemenented) range512 above the (not yet implemented) other encodings. This means that range512 is used whenever possible, not only when it is optimal. Thus the encoding will only fail, when it not *possible* to use range512. The patch has a similar effect like commit 10eb96e6b1e and replaces it. Ticket: OW#1061 Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 6 ++++-- openbsc/tests/si/si_test.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index c52743e..d12c907 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -160,12 +160,14 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) max = arfcns[size - 1] - arfcns[0]; *f0 = arfcns[0]; + if (max < 512 && size <= 18) + return ARFCN_RANGE_512; + + /* The following are nyi, so they are checked last */ if (max < 128 && size <= 29) return ARFCN_RANGE_128; if (max < 256 && size <= 22) return ARFCN_RANGE_256; - if (max < 512 && size <= 18) - return ARFCN_RANGE_512; if (max < 1024 && size <= 17) return ARFCN_RANGE_1024; diff --git a/openbsc/tests/si/si_test.c b/openbsc/tests/si/si_test.c index fd840f3..695ae6d 100644 --- a/openbsc/tests/si/si_test.c +++ b/openbsc/tests/si/si_test.c @@ -137,11 +137,11 @@ int main(int argc, char **argv) } i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); - VERIFY(i, ==, ARFCN_RANGE_128); + VERIFY(i, ==, ARFCN_RANGE_512); VERIFY(f0, ==, 1); i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); - VERIFY(i, ==, ARFCN_RANGE_256); + VERIFY(i, ==, ARFCN_RANGE_512); VERIFY(f0, ==, 1); i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:18 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:18 +0100 Subject: [PATCH 4/9] si/test: Add tests for range encoding/decoding In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-4-git-send-email-jerlbeck@sysmocom.de> This commit adds test range encoding tests. They check the property decoding(encoding(L)) = L and optionally dump the results and encoded sequences to stdout. There a 2 test modes: - A list of fixed tests - A random number based test loop per ARFCN list size (only dumps the first failing test) Sponsored-by: On-Waves ehf --- openbsc/tests/gsm0408/Makefile.am | 1 + openbsc/tests/gsm0408/gsm0408_test.c | 216 +++++++++++++++++++++++++++++++++ openbsc/tests/gsm0408/gsm0408_test.ok | 48 ++++++++ 3 files changed, 265 insertions(+) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index b000c08..1c29ece 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -8,4 +8,5 @@ gsm0408_test_SOURCES = gsm0408_test.c gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -ldbi diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 60a151f..721b283 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #define COMPARE(result, op, value) \ if (!((result) op (value))) {\ @@ -94,10 +96,224 @@ static void test_mi_functionality(void) COMPARE_STR(mi_parsed, imsi_even); } +struct { + int range; + int arfcns_num; + int arfcns[RANGE_ENC_MAX_ARFCNS]; +} arfcn_test_ranges[] = { + {ARFCN_RANGE_512, 12, + { 1, 12, 31, 51, 57, 91, 97, 98, 113, 117, 120, 125 }}, + {ARFCN_RANGE_512, 17, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }}, + {ARFCN_RANGE_512, 18, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }}, + {ARFCN_RANGE_512, 18, + { 1, 17, 31, 45, 58, 79, 81, 97, + 113, 127, 213, 277, 287, 311, 331, 391, + 417, 511 }}, + {ARFCN_RANGE_512, 6, + { 1, 17, 31, 45, 58, 79 }}, + {ARFCN_RANGE_512, 6, + { 10, 17, 31, 45, 58, 79 }}, + {ARFCN_RANGE_1024, 17, + { 0, 17, 31, 45, 58, 79, 81, 97, + 113, 127, 213, 277, 287, 311, 331, 391, + 1023 }}, + {ARFCN_RANGE_1024, 16, + { 17, 31, 45, 58, 79, 81, 97, 113, + 127, 213, 277, 287, 311, 331, 391, 1023 }}, + {-1} +}; + +static int test_single_range_encoding(int range, const int *orig_arfcns, + int arfcns_num, int silent) +{ + int arfcns[RANGE_ENC_MAX_ARFCNS]; + int w[RANGE_ENC_MAX_ARFCNS]; + int f0_included = 0; + int rc, f0; + uint8_t chan_list[16] = {0}; + struct gsm_sysinfo_freq dec_freq[1024] = {{0}}; + int dec_arfcns[RANGE_ENC_MAX_ARFCNS] = {0}; + int dec_arfcns_count = 0; + int arfcns_used = 0; + int i; + + arfcns_used = arfcns_num; + memmove(arfcns, orig_arfcns, sizeof(arfcns)); + + f0 = arfcns[0]; + /* + * Manipulate the ARFCN list according to the rules in J4 depending + * on the selected range. + */ + arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + f0, &f0_included); + + memset(w, 0, sizeof(w)); + rc = range_enc_arfcns(range, arfcns, arfcns_used, w, 0); + if (rc != 0) { + printf("Cannot compute range W(k), rc = %d\n", rc); + return 1; + } + + if (!silent) + fprintf(stderr, "range=%d, arfcns_used=%d, f0=%d, f0_included=%d\n", + range, arfcns_used, f0, f0_included); + + /* Select the range and the amount of bits needed */ + switch (range) { + case ARFCN_RANGE_128: + rc = range_enc_range128(chan_list, f0, w); + break; + case ARFCN_RANGE_256: + rc = range_enc_range256(chan_list, f0, w); + break; + case ARFCN_RANGE_512: + rc = range_enc_range512(chan_list, f0, w); + break; + case ARFCN_RANGE_1024: + rc = range_enc_range1024(chan_list, f0, f0_included, w); + break; + default: + return 1; + }; + if (rc != 0) { + printf("Cannot encode range, rc = %d\n", rc); + return 1; + } + + if (!silent) + printf("chan_list = %s\n", + osmo_hexdump(chan_list, sizeof(chan_list))); + + rc = gsm48_decode_freq_list(dec_freq, chan_list, sizeof(chan_list), + 0xfe, 1); + if (rc != 0) { + printf("Cannot decode freq list, rc = %d\n", rc); + return 1; + } + + for (i = 0; i < ARRAY_SIZE(dec_freq); i++) { + if (dec_freq[i].mask && + dec_arfcns_count < ARRAY_SIZE(dec_arfcns)) + dec_arfcns[dec_arfcns_count++] = i; + } + + if (!silent) { + printf("Decoded freqs %d (expected %d)\n", + dec_arfcns_count, arfcns_num); + printf("Decoded: "); + for (i = 0; i < dec_arfcns_count; i++) { + printf("%d ", dec_arfcns[i]); + if (dec_arfcns[i] != orig_arfcns[i]) + printf("(!= %d) ", orig_arfcns[i]); + } + printf("\n"); + } + + if (dec_arfcns_count != arfcns_num) { + printf("Wrong number of arfcns\n"); + return 1; + } + + if (memcmp(dec_arfcns, orig_arfcns, sizeof(dec_arfcns)) != 0) { + printf("Decoding error, got wrong freqs\n"); + fprintf(stderr, " w = "); + for (i = 0; i < ARRAY_SIZE(w); i++) + fprintf(stderr, "%d ", w[i]); + fprintf(stderr, "\n"); + return 1; + } + + return 0; +} + +static void test_random_range_encoding(int range, int max_arfcn_num) +{ + int arfcns_num = 0; + int test_idx; + int rc, max_count; + int num_tests = 1024; + + printf("Random range test: range %d, max num ARFCNs %d\n", + range, max_arfcn_num); + + srandom(1); + + for (max_count = 1; max_count < max_arfcn_num; max_count++) { + for (test_idx = 0; test_idx < num_tests; test_idx++) { + int count; + int i; + int min_freq = 0; + + int rnd_arfcns[RANGE_ENC_MAX_ARFCNS] = {0}; + char rnd_arfcns_set[1024] = {0}; + + if (range < ARFCN_RANGE_1024) + min_freq = random() % (1023 - range); + + for (count = max_count; count; ) { + int arfcn = min_freq + random() % (range + 1); + OSMO_ASSERT(arfcn < ARRAY_SIZE(rnd_arfcns_set)); + + if (!rnd_arfcns_set[arfcn]) { + rnd_arfcns_set[arfcn] = 1; + count -= 1; + } + } + + arfcns_num = 0; + for (i = 0; i < ARRAY_SIZE(rnd_arfcns_set); i++) + if (rnd_arfcns_set[i]) + rnd_arfcns[arfcns_num++] = i; + + rc = test_single_range_encoding(range, rnd_arfcns, + arfcns_num, 1); + if (rc != 0) { + printf("Failed on test %d, range %d, num ARFCNs %d\n", + test_idx, range, max_count); + test_single_range_encoding(range, rnd_arfcns, + arfcns_num, 0); + return; + } + } + } +} + +static void test_range_encoding() +{ + int *arfcns; + int arfcns_num = 0; + int test_idx; + int range; + + for (test_idx = 0; arfcn_test_ranges[test_idx].arfcns_num > 0; test_idx++) + { + arfcns_num = arfcn_test_ranges[test_idx].arfcns_num; + arfcns = &arfcn_test_ranges[test_idx].arfcns[0]; + range = arfcn_test_ranges[test_idx].range; + + printf("Range test %d: range %d, num ARFCNs %d\n", + test_idx, range, arfcns_num); + + test_single_range_encoding(range, arfcns, arfcns_num, 0); + } + + test_random_range_encoding(ARFCN_RANGE_128, 29); + test_random_range_encoding(ARFCN_RANGE_256, 22); + test_random_range_encoding(ARFCN_RANGE_512, 18); + test_random_range_encoding(ARFCN_RANGE_1024, 16); +} + int main(int argc, char **argv) { + osmo_init_logging(&log_info); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + test_location_area_identifier(); test_mi_functionality(); + test_range_encoding(); printf("Done.\n"); return EXIT_SUCCESS; diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index 52c601e..a92b879 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -2,4 +2,52 @@ Testing test location area identifier Testing parsing and generating TMSI/IMSI hex: 17 08 99 78 56 34 12 90 78 36 hex: 17 09 91 78 56 34 12 90 78 56 f4 +Range test 0: range 511, num ARFCNs 12 +chan_list = 88 00 98 34 85 36 7c 50 22 dc 5e ec 00 00 00 00 +Decoded freqs 12 (expected 12) +Decoded: 1 12 31 51 57 91 97 98 113 117 120 125 +Range test 1: range 511, num ARFCNs 17 +chan_list = 88 00 82 7f 01 3f 7e 04 0b ff ff fc 10 41 07 e0 +Decoded freqs 17 (expected 17) +Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +Range test 2: range 511, num ARFCNs 18 +chan_list = 88 00 82 7f 01 7f 7e 04 0b ff ff fc 10 41 07 ff +Decoded freqs 18 (expected 18) +Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +Range test 3: range 511, num ARFCNs 18 +chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 76 +Decoded freqs 18 (expected 18) +Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 507 (!= 511) +Decoding error, got wrong freqs +Range test 4: range 511, num ARFCNs 6 +chan_list = 88 00 8b 3c 88 b9 6b 00 00 00 00 00 00 00 00 00 +Decoded freqs 6 (expected 6) +Decoded: 1 17 31 45 58 79 +Range test 5: range 511, num ARFCNs 6 +chan_list = 88 05 08 fc 88 b9 6b 00 00 00 00 00 00 00 00 00 +Decoded freqs 6 (expected 6) +Decoded: 10 17 31 45 58 79 +Range test 6: range 1023, num ARFCNs 17 +Cannot encode range, rc = -1 +Range test 7: range 1023, num ARFCNs 16 +Cannot encode range, rc = -1 +Random range test: range 127, max num ARFCNs 29 +Cannot encode range, rc = -1 +Failed on test 0, range 127, num ARFCNs 1 +Cannot encode range, rc = -1 +Random range test: range 255, max num ARFCNs 22 +Cannot encode range, rc = -1 +Failed on test 0, range 255, num ARFCNs 1 +Cannot encode range, rc = -1 +Random range test: range 511, max num ARFCNs 18 +Decoding error, got wrong freqs +Failed on test 0, range 511, num ARFCNs 17 +chan_list = 88 21 55 fc da d7 76 03 31 2f ed 45 dc 93 d6 80 +Decoded freqs 17 (expected 17) +Decoded: 66 81 161 250 314 343 383 (!= 380) 395 396 397 409 429 505 506 516 518 545 +Decoding error, got wrong freqs +Random range test: range 1023, max num ARFCNs 16 +Cannot encode range, rc = -1 +Failed on test 0, range 1023, num ARFCNs 1 +Cannot encode range, rc = -1 Done. -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:19 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:19 +0100 Subject: [PATCH 5/9] si/test: Merge si tests into gsm48 tests In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-5-git-send-email-jerlbeck@sysmocom.de> Currently tests covering features of the GSM 04.08 specification are spread over the si and gsm0408 subdirs in tests. This commit merges all tests from 'si' into 'gsm0408' and removes the 'si' test sub-directory. Sponsored-by: On-Waves ehf --- openbsc/configure.ac | 1 - openbsc/tests/Makefile.am | 2 +- openbsc/tests/gsm0408/gsm0408_test.c | 146 ++++++++++++++++++++++++++++++ openbsc/tests/gsm0408/gsm0408_test.ok | 20 +++++ openbsc/tests/si/Makefile.am | 12 --- openbsc/tests/si/si_test.c | 156 --------------------------------- openbsc/tests/si/si_test.ok | 20 ----- openbsc/tests/testsuite.at | 6 -- 8 files changed, 167 insertions(+), 196 deletions(-) delete mode 100644 openbsc/tests/si/Makefile.am delete mode 100644 openbsc/tests/si/si_test.c delete mode 100644 openbsc/tests/si/si_test.ok diff --git a/openbsc/configure.ac b/openbsc/configure.ac index fe99569..5d29af7 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -166,7 +166,6 @@ AC_OUTPUT( tests/mgcp/Makefile tests/gprs/Makefile tests/gbproxy/Makefile - tests/si/Makefile tests/abis/Makefile tests/smpp/Makefile tests/trau/Makefile diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index d4bb954..31b2bb4 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = gsm0408 db channel mgcp gprs si abis gbproxy trau +SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau if BUILD_NAT SUBDIRS += bsc-nat bsc-nat-trie diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 721b283..246e201 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -42,6 +42,16 @@ exit(-1); \ } +#define DBG(...) + +#define VERIFY(res, cmp, wanted) \ + if (!(res cmp wanted)) { \ + printf("ASSERT failed: %s:%d Wanted: %d %s %d\n", \ + __FILE__, __LINE__, res, # cmp, wanted); \ + } + + + /* * Test Location Area Identifier formatting. Table 10.5.3 of 04.08 */ @@ -306,6 +316,138 @@ static void test_range_encoding() test_random_range_encoding(ARFCN_RANGE_1024, 16); } +static int freqs1[] = { + 12, 70, 121, 190, 250, 320, 401, 475, 520, 574, 634, 700, 764, 830, 905, 980 +}; + +static int freqs2[] = { + 402, 460, 1, 67, 131, 197, 272, 347, +}; + +static int freqs3[] = { + 68, 128, 198, 279, 353, 398, 452, + +}; + +static int w_out[] = { + 122, 2, 69, 204, 75, 66, 60, 70, 83, 3, 24, 67, 54, 64, 70, 9, +}; + +static int range128[] = { + 1, 1 + 127, +}; + +static int range256[] = { + 1, 1 + 128, +}; + +static int range512[] = { + 1, 1+ 511, +}; + + +static void test_arfcn_filter() +{ + int arfcns[50], i, res, f0_included; + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + + /* check that the arfcn is taken out. f0_included is only set for Range1024 */ + f0_included = 24; + res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), + arfcns[0], &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); + VERIFY(f0_included, ==, 0); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); + + /* check with range1024 */ + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), + arfcns[0], &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); + VERIFY(f0_included, ==, 1); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); + + /* check with range1024, not included */ + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), + 11, &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns)); + VERIFY(f0_included, ==, 0); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1); +} + +static void test_print_encoding() +{ + int rc; + int w[17]; + uint8_t chan_list[16]; + memset(chan_list, 0x23, sizeof(chan_list)); + + for (rc = 0; rc < ARRAY_SIZE(w); ++rc) + switch (rc % 3) { + case 0: + w[rc] = 0xAAAA; + break; + case 1: + w[rc] = 0x5555; + break; + case 2: + w[rc] = 0x9696; + break; + } + + rc = range_enc_range512(chan_list, (1 << 9) | 0x96, w); + VERIFY(rc, ==, 0); + + printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list))); +} + +static void test_si_range_helpers() +{ + int ws[(sizeof(freqs1)/sizeof(freqs1[0]))]; + int i, f0 = 0xFFFFFF; + + memset(&ws[0], 0x23, sizeof(ws)); + + i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs1[i]); + VERIFY(i, ==, 2); + + i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs2[i]); + VERIFY(i, ==, 2); + + i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs3[i]); + VERIFY(i, ==, 0); + + i = range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0); + VERIFY(i, ==, 0); + + for (i = 0; i < sizeof(freqs1)/sizeof(freqs1[0]); ++i) { + printf("w[%d]=%d\n", i, ws[i]); + VERIFY(ws[i], ==, w_out[i]); + } + + i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); + VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(f0, ==, 1); + + i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); + VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(f0, ==, 1); + + i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); + VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(f0, ==, 1); +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); @@ -313,6 +455,10 @@ int main(int argc, char **argv) test_location_area_identifier(); test_mi_functionality(); + + test_si_range_helpers(); + test_arfcn_filter(); + test_print_encoding(); test_range_encoding(); printf("Done.\n"); diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index a92b879..5458669 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -2,6 +2,26 @@ Testing test location area identifier Testing parsing and generating TMSI/IMSI hex: 17 08 99 78 56 34 12 90 78 36 hex: 17 09 91 78 56 34 12 90 78 56 f4 +Element is: 2 => freqs[i] = 121 +Element is: 2 => freqs[i] = 1 +Element is: 0 => freqs[i] = 68 +w[0]=122 +w[1]=2 +w[2]=69 +w[3]=204 +w[4]=75 +w[5]=66 +w[6]=60 +w[7]=70 +w[8]=83 +w[9]=3 +w[10]=24 +w[11]=67 +w[12]=54 +w[13]=64 +w[14]=70 +w[15]=9 +Range512: 89 4b 2a 95 65 95 55 2c a9 55 aa 55 6a 95 59 55 Range test 0: range 511, num ARFCNs 12 chan_list = 88 00 98 34 85 36 7c 50 22 dc 5e ec 00 00 00 00 Decoded freqs 12 (expected 12) diff --git a/openbsc/tests/si/Makefile.am b/openbsc/tests/si/Makefile.am deleted file mode 100644 index 795bd30..0000000 --- a/openbsc/tests/si/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) - -EXTRA_DIST = si_test.ok - -noinst_PROGRAMS = si_test - -si_test_SOURCES = si_test.c - -si_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/openbsc/tests/si/si_test.c b/openbsc/tests/si/si_test.c deleted file mode 100644 index 695ae6d..0000000 --- a/openbsc/tests/si/si_test.c +++ /dev/null @@ -1,156 +0,0 @@ - - -#include -#include -#include - -#include - -#include - -#define DBG(...) - -#define VERIFY(res, cmp, wanted) \ - if (!(res cmp wanted)) { \ - printf("ASSERT failed: %s:%d Wanted: %d %s %d\n", \ - __FILE__, __LINE__, res, # cmp, wanted); \ - } - - -static int freqs1[] = { - 12, 70, 121, 190, 250, 320, 401, 475, 520, 574, 634, 700, 764, 830, 905, 980 -}; - -static int freqs2[] = { - 402, 460, 1, 67, 131, 197, 272, 347, -}; - -static int freqs3[] = { - 68, 128, 198, 279, 353, 398, 452, - -}; - -static int w_out[] = { - 122, 2, 69, 204, 75, 66, 60, 70, 83, 3, 24, 67, 54, 64, 70, 9, -}; - -static int range128[] = { - 1, 1 + 127, -}; - -static int range256[] = { - 1, 1 + 128, -}; - -static int range512[] = { - 1, 1+ 511, -}; - - -static void test_arfcn_filter() -{ - int arfcns[50], i, res, f0_included; - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - - /* check that the arfcn is taken out. f0_included is only set for Range1024 */ - f0_included = 24; - res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 0); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); - - /* check with range1024 */ - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 1); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); - - /* check with range1024, not included */ - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - 11, &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns)); - VERIFY(f0_included, ==, 0); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1); -} - -static void test_print_encoding() -{ - int rc; - int w[17]; - uint8_t chan_list[16]; - memset(chan_list, 0x23, sizeof(chan_list)); - - for (rc = 0; rc < ARRAY_SIZE(w); ++rc) - switch (rc % 3) { - case 0: - w[rc] = 0xAAAA; - break; - case 1: - w[rc] = 0x5555; - break; - case 2: - w[rc] = 0x9696; - break; - } - - rc = range_enc_range512(chan_list, (1 << 9) | 0x96, w); - VERIFY(rc, ==, 0); - - printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list))); -} - -int main(int argc, char **argv) -{ - int ws[(sizeof(freqs1)/sizeof(freqs1[0]))]; - int i, f0 = 0xFFFFFF; - - memset(&ws[0], 0x23, sizeof(ws)); - - i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs1[i]); - VERIFY(i, ==, 2); - - i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs2[i]); - VERIFY(i, ==, 2); - - i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs3[i]); - VERIFY(i, ==, 0); - - i = range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0); - VERIFY(i, ==, 0); - - for (i = 0; i < sizeof(freqs1)/sizeof(freqs1[0]); ++i) { - printf("w[%d]=%d\n", i, ws[i]); - VERIFY(ws[i], ==, w_out[i]); - } - - i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); - VERIFY(f0, ==, 1); - - i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); - VERIFY(f0, ==, 1); - - i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); - VERIFY(f0, ==, 1); - - - test_arfcn_filter(); - test_print_encoding(); - - return 0; -} diff --git a/openbsc/tests/si/si_test.ok b/openbsc/tests/si/si_test.ok deleted file mode 100644 index 6a3ee51..0000000 --- a/openbsc/tests/si/si_test.ok +++ /dev/null @@ -1,20 +0,0 @@ -Element is: 2 => freqs[i] = 121 -Element is: 2 => freqs[i] = 1 -Element is: 0 => freqs[i] = 68 -w[0]=122 -w[1]=2 -w[2]=69 -w[3]=204 -w[4]=75 -w[5]=66 -w[6]=60 -w[7]=70 -w[8]=83 -w[9]=3 -w[10]=24 -w[11]=67 -w[12]=54 -w[13]=64 -w[14]=70 -w[15]=9 -Range512: 89 4b 2a 95 65 95 55 2c a9 55 aa 55 6a 95 59 55 diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 652cfe9..b2c5518 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -57,12 +57,6 @@ cat $abs_srcdir/bsc-nat-trie/bsc_nat_trie_test.ok > expout AT_CHECK([$abs_top_builddir/tests/bsc-nat-trie/bsc_nat_trie_test], [], [expout], [ignore]) AT_CLEANUP -AT_SETUP([si]) -AT_KEYWORDS([si]) -cat $abs_srcdir/si/si_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/si/si_test], [], [expout], [ignore]) -AT_CLEANUP - AT_SETUP([abis]) AT_KEYWORDS([abis]) cat $abs_srcdir/abis/abis_test.ok > expout -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:20 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:20 +0100 Subject: [PATCH 6/9] si: Fix range512 encoding In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-6-git-send-email-jerlbeck@sysmocom.de> This patch fixes a bug in the range encoder that leads to wrong encoding when 17 or more ARFCNs are encoded. Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 2 +- openbsc/tests/gsm0408/gsm0408_test.ok | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index d12c907..edd886f 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -258,7 +258,7 @@ int range_enc_range512(uint8_t *chan_list, int f0, int *w) range512->w15 = HIGH_BITS(w, 15, 6, 6); /* W(16) */ range512->w16_hi = HIGH_BITS(w, 16, 5, 2); - range512->w16_lo = HIGH_BITS(w, 16, 5, 3); + range512->w16_lo = LOW_BITS(w, 16, 5, 3); /* W(17) */ range512->w17 = HIGH_BITS(w, 17, 5, 5); diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index 5458669..dab495d 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -35,10 +35,9 @@ chan_list = 88 00 82 7f 01 7f 7e 04 0b ff ff fc 10 41 07 ff Decoded freqs 18 (expected 18) Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Range test 3: range 511, num ARFCNs 18 -chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 76 +chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 f6 Decoded freqs 18 (expected 18) -Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 507 (!= 511) -Decoding error, got wrong freqs +Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 511 Range test 4: range 511, num ARFCNs 6 chan_list = 88 00 8b 3c 88 b9 6b 00 00 00 00 00 00 00 00 00 Decoded freqs 6 (expected 6) @@ -60,12 +59,6 @@ Cannot encode range, rc = -1 Failed on test 0, range 255, num ARFCNs 1 Cannot encode range, rc = -1 Random range test: range 511, max num ARFCNs 18 -Decoding error, got wrong freqs -Failed on test 0, range 511, num ARFCNs 17 -chan_list = 88 21 55 fc da d7 76 03 31 2f ed 45 dc 93 d6 80 -Decoded freqs 17 (expected 17) -Decoded: 66 81 161 250 314 343 383 (!= 380) 395 396 397 409 429 505 506 516 518 545 -Decoding error, got wrong freqs Random range test: range 1023, max num ARFCNs 16 Cannot encode range, rc = -1 Failed on test 0, range 1023, num ARFCNs 1 -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:21 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:21 +0100 Subject: [PATCH 7/9] si: Fix range1024 encoding In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-7-git-send-email-jerlbeck@sysmocom.de> f0 is currently set to arfcns[0] in range_enc_determine_range(), while GSM 04.08 requires f0 to be ARFCN 0 in range1024 encoding. This patch modifies range_enc_determine_range() to force f0 to be 0 if this encoding is used. This way the case distinction in range_enc_filter_arfcns() is not longer necessary. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/arfcn_range_encode.h | 2 +- openbsc/src/libbsc/arfcn_range_encode.c | 44 +++++++++++--------------- openbsc/src/libbsc/system_information.c | 2 +- openbsc/tests/gsm0408/gsm0408_test.c | 24 +++++++------- 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/openbsc/include/openbsc/arfcn_range_encode.h b/openbsc/include/openbsc/arfcn_range_encode.h index 7a6fff0..bd85d6a 100644 --- a/openbsc/include/openbsc/arfcn_range_encode.h +++ b/openbsc/include/openbsc/arfcn_range_encode.h @@ -16,7 +16,7 @@ enum { int range_enc_determine_range(const int *arfcns, int size, int *f0_out); int range_enc_arfcns(const int rng, const int *arfcns, int sze, int *out, int idx); int range_enc_find_index(const int rng, const int *arfcns, int size); -int range_enc_filter_arfcns(const int rng, int *arfcns, const int sze, const int f0, int *f0_included); +int range_enc_filter_arfcns(int *arfcns, const int sze, const int f0, int *f0_included); int range_enc_range128(uint8_t *chan_list, int f0, int *w); int range_enc_range256(uint8_t *chan_list, int f0, int *w); diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index edd886f..17c347f 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -144,7 +144,9 @@ int range_enc_arfcns(const int range, */ /** * This implements the range determination as described in GSM 04.08 J4. The - * result will be a base frequency f0 and the range to use. + * result will be a base frequency f0 and the range to use. Note that for range + * 1024 encoding f0 always refers to ARFCN 0 even if it is not an element of + * the arfcns list. * * \param[in] arfcns The input frequencies, they must be sorted, lowest number first * \param[in] size The length of the array @@ -168,8 +170,10 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) return ARFCN_RANGE_128; if (max < 256 && size <= 22) return ARFCN_RANGE_256; - if (max < 1024 && size <= 17) + if (max < 1024 && size <= 17) { + *f0 = 0; return ARFCN_RANGE_1024; + } return ARFCN_RANGE_INVALID; } @@ -273,34 +277,24 @@ int range_enc_range1024(uint8_t *chan_list, int f0, int f0_included, int *w) return -1; } -int range_enc_filter_arfcns(const int range, int *arfcns, - const int size, const int f0, int *f0_included) +int range_enc_filter_arfcns(int *arfcns, + const int size, const int f0, int *f0_included) { int i, j = 0; *f0_included = 0; - if (range == ARFCN_RANGE_1024) { - for (i = 0; i < size; ++i) { - if (arfcns[i] == f0) { - *f0_included = 1; - continue; - } - - /* copy and subtract */ - arfcns[j++] = mod(arfcns[i] - 1, 1024); - } - } else { - for (i = 0; i < size; ++i) { - /* - * Appendix J.4 says the following: - * All frequencies except F(0), minus F(0) + 1. - * I assume we need to exclude it here. - */ - if (arfcns[i] == f0) - continue; - - arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); + for (i = 0; i < size; ++i) { + /* + * Appendix J.4 says the following: + * All frequencies except F(0), minus F(0) + 1. + * I assume we need to exclude it here. + */ + if (arfcns[i] == f0) { + *f0_included = 1; + continue; } + + arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); } return j; diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 5f46bf9..95ac736 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -197,7 +197,7 @@ static int enc_freq_lst_range(uint8_t *chan_list, * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 246e201..3218379 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -152,12 +152,12 @@ static int test_single_range_encoding(int range, const int *orig_arfcns, arfcns_used = arfcns_num; memmove(arfcns, orig_arfcns, sizeof(arfcns)); - f0 = arfcns[0]; + f0 = range == ARFCN_RANGE_1024 ? 0 : arfcns[0]; /* * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); @@ -354,28 +354,28 @@ static void test_arfcn_filter() /* check that the arfcn is taken out. f0_included is only set for Range1024 */ f0_included = 24; - res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), arfcns[0], &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 0); + VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); - /* check with range1024 */ + /* check with range1024, ARFCN 0 is included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); + arfcns[i] = i * 2; + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); + VERIFY(arfcns[i], ==, (i + 1) * 2 - 1); - /* check with range1024, not included */ + /* check with range1024, ARFCN 0 not included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - 11, &f0_included); + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns)); VERIFY(f0_included, ==, 0); for (i = 0; i < res; ++i) -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:22 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:22 +0100 Subject: [PATCH 8/9] si: Add generic range w(k) encoder In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-8-git-send-email-jerlbeck@sysmocom.de> Currently the encoding of the chan_list is done by a hard-coded sequence of macros that closely resembles figure 10.5.16 in 3GPP TS 04.08. This patch replaces this by an algorithmic solution that can be used for all range encodings and is based on the property W(2^i) to W(2^(i+1)-1) are on w1_len-i bits when present (see section 10.5.2.13 in TS 04.08). Ticket: OW#1061 Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 141 ++++++++++++++++++------------- 1 file changed, 83 insertions(+), 58 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index 17c347f..3e5b1fc 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -178,16 +178,6 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) return ARFCN_RANGE_INVALID; } -/* - * The below is easier is to write in four methods than - * to use the max_bits. The encoding is so screwed.. as - * the bits need to be put in place in the wrong order.. - */ -#define HIGH_BITS(w, index, bits, offset) \ - (w[index - 1] >> (bits - offset)) -#define LOW_BITS(w, index, bits, offset) \ - (w[index - 1]) - static void write_orig_arfcn(uint8_t *chan_list, int f0) { chan_list[0] |= (f0 >> 9) & 1; @@ -195,6 +185,88 @@ static void write_orig_arfcn(uint8_t *chan_list, int f0) chan_list[2] = (f0 & 1) << 7; } +static void write_all_wn(uint8_t *chan_list, int bit_offs, + int *w, int w_size, int w1_len) +{ + int octet_offs = 0; /* offset into chan_list */ + int wk_len = w1_len; /* encoding size in bits of w[k] */ + int k; /* 1 based */ + int level = 0; /* tree level, top level = 0 */ + int lvl_left = 1; /* nodes per tree level */ + + /* W(2^i) to W(2^(i+1)-1) are on w1_len-i bits when present */ + + for (k = 1; k <= w_size; k++) { + int wk_left = wk_len; + DEBUGP(DRR, + "k=%d, wk_len=%d, offs=%d:%d, level=%d, " + "lvl_left=%d\n", + k, wk_len, octet_offs, bit_offs, level, lvl_left); + + while (wk_left > 0) { + int cur_bits = 8 - bit_offs; + int cur_mask; + int wk_slice; + + if (cur_bits > wk_left) + cur_bits = wk_left; + + cur_mask = ((1 << cur_bits) - 1); + + DEBUGP(DRR, + " wk_left=%d, cur_bits=%d, offs=%d:%d\n", + wk_left, cur_bits, octet_offs, bit_offs); + + /* advance */ + wk_left -= cur_bits; + bit_offs += cur_bits; + + /* right aligned wk data for current out octet */ + wk_slice = (w[k-1] >> wk_left) & cur_mask; + + /* cur_bits now contains the number of bits + * that are to be copied from wk to the chan_list. + * wk_left is set to the number of bits that must + * not yet be copied. + * bit_offs points after the bit area that is going to + * be overwritten: + * + * wk_left + * | + * v + * wk: WWWWWWWWWWW + * |||||<-- wk_slice, cur_bits=5 + * --WWWWW- + * ^ + * | + * bit_offs + */ + + DEBUGP(DRR, + " wk=%02x, slice=%02x/%02x, cl=%02x\n", + w[k-1], wk_slice, cur_mask, wk_slice << (8 - bit_offs)); + + chan_list[octet_offs] &= ~(cur_mask << (8 - bit_offs)); + chan_list[octet_offs] |= wk_slice << (8 - bit_offs); + + /* adjust output */ + if (bit_offs == 8) { + bit_offs = 0; + octet_offs += 1; + } + } + + /* adjust bit sizes */ + lvl_left -= 1; + if (!lvl_left) { + /* completed tree level, advance to next */ + level += 1; + lvl_left = 1 << level; + wk_len -= 1; + } + } +} + int range_enc_range128(uint8_t *chan_list, int f0, int *w) { chan_list[0] = 0x8C; @@ -215,57 +287,10 @@ int range_enc_range256(uint8_t *chan_list, int f0, int *w) int range_enc_range512(uint8_t *chan_list, int f0, int *w) { - struct gsm48_range_512 *range512; chan_list[0] = 0x88; write_orig_arfcn(chan_list, f0); - range512 = (struct gsm48_range_512 *) &chan_list[0]; - - /* W(1) */ - range512->w1_hi = HIGH_BITS(w, 1, 9, 7); - range512->w1_lo = LOW_BITS (w, 1, 9, 2); - /* W(2) */ - range512->w2_hi = HIGH_BITS(w, 2, 8, 6); - range512->w2_lo = LOW_BITS (w, 2, 8, 2); - /* W(3) */ - range512->w3_hi = HIGH_BITS(w, 3, 8, 6); - range512->w3_lo = LOW_BITS (w, 3, 8, 2); - /* W(4) */ - range512->w4_hi = HIGH_BITS(w, 4, 7, 6); - range512->w4_lo = LOW_BITS (w, 4, 7, 1); - /* W(5) */ - range512->w5 = HIGH_BITS(w, 5, 7, 7); - /* W(6) */ - range512->w6 = HIGH_BITS(w, 6, 7, 7); - /* W(7) */ - range512->w7_hi = HIGH_BITS(w, 7, 7, 1); - range512->w7_lo = LOW_BITS (w, 7, 7, 6); - /* W(8) */ - range512->w8_hi = HIGH_BITS(w, 8, 6, 2); - range512->w8_lo = LOW_BITS (w, 8, 6, 4); - /* W(9) */ - range512->w9_hi = HIGH_BITS(w, 9, 6, 4); - range512->w9_lo = LOW_BITS(w, 9, 6, 2); - /* W(10) */ - range512->w10 = HIGH_BITS(w, 10, 6, 6); - /* W(11) */ - range512->w11 = HIGH_BITS(w, 11, 6, 6); - /* W(12) */ - range512->w12_hi = HIGH_BITS(w, 12, 6, 2); - range512->w12_lo = LOW_BITS (w, 12, 6, 4); - /* W(13) */ - range512->w13_hi = HIGH_BITS(w, 13, 6, 4); - range512->w13_lo = LOW_BITS(w, 13, 6, 2); - /* W(14) */ - range512->w14 = HIGH_BITS(w, 14, 6, 6); - /* W(15) */ - range512->w15 = HIGH_BITS(w, 15, 6, 6); - /* W(16) */ - range512->w16_hi = HIGH_BITS(w, 16, 5, 2); - range512->w16_lo = LOW_BITS(w, 16, 5, 3); - /* W(17) */ - range512->w17 = HIGH_BITS(w, 17, 5, 5); - + write_all_wn(&chan_list[2], 1, w, 17, 9); return 0; } -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Jan 14 13:24:23 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 14 Jan 2014 14:24:23 +0100 Subject: [PATCH 9/9] si: Implement range 128, 256, 1024 encoding In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389705863-3730-9-git-send-email-jerlbeck@sysmocom.de> This commit adds the implementation of these range formats to the encoder. In addition, the work-around that tried range 512 first is removed, so that the selection is primarily based on the max distance between frequencies. Ticket: OW#1061 Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 18 ++++++++---------- openbsc/tests/gsm0408/gsm0408_test.c | 4 ++-- openbsc/tests/gsm0408/gsm0408_test.ok | 17 ++++++----------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index 3e5b1fc..e67bf0a 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -162,14 +162,12 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) max = arfcns[size - 1] - arfcns[0]; *f0 = arfcns[0]; - if (max < 512 && size <= 18) - return ARFCN_RANGE_512; - - /* The following are nyi, so they are checked last */ if (max < 128 && size <= 29) return ARFCN_RANGE_128; if (max < 256 && size <= 22) return ARFCN_RANGE_256; + if (max < 512 && size <= 18) + return ARFCN_RANGE_512; if (max < 1024 && size <= 17) { *f0 = 0; return ARFCN_RANGE_1024; @@ -272,8 +270,8 @@ int range_enc_range128(uint8_t *chan_list, int f0, int *w) chan_list[0] = 0x8C; write_orig_arfcn(chan_list, f0); - LOGP(DRR, LOGL_ERROR, "Range128 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[2], 1, w, 28, 7); + return 0; } int range_enc_range256(uint8_t *chan_list, int f0, int *w) @@ -281,8 +279,8 @@ int range_enc_range256(uint8_t *chan_list, int f0, int *w) chan_list[0] = 0x8A; write_orig_arfcn(chan_list, f0); - LOGP(DRR, LOGL_ERROR, "Range256 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[2], 1, w, 21, 8); + return 0; } int range_enc_range512(uint8_t *chan_list, int f0, int *w) @@ -298,8 +296,8 @@ int range_enc_range1024(uint8_t *chan_list, int f0, int f0_included, int *w) { chan_list[0] = 0x80 | (f0_included << 2); - LOGP(DRR, LOGL_ERROR, "Range1024 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[0], 6, w, 16, 10); + return 0; } int range_enc_filter_arfcns(int *arfcns, diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 3218379..894eb0f 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -436,11 +436,11 @@ static void test_si_range_helpers() } i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(i, ==, ARFCN_RANGE_128); VERIFY(f0, ==, 1); i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(i, ==, ARFCN_RANGE_256); VERIFY(f0, ==, 1); i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index dab495d..3d3c4e6 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -47,20 +47,15 @@ chan_list = 88 05 08 fc 88 b9 6b 00 00 00 00 00 00 00 00 00 Decoded freqs 6 (expected 6) Decoded: 10 17 31 45 58 79 Range test 6: range 1023, num ARFCNs 17 -Cannot encode range, rc = -1 +chan_list = 84 71 e4 ab b9 58 05 cb 39 17 fd b0 75 62 0f 2f +Decoded freqs 17 (expected 17) +Decoded: 0 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 1023 Range test 7: range 1023, num ARFCNs 16 -Cannot encode range, rc = -1 +chan_list = 80 71 e4 ab b9 58 05 cb 39 17 fd b0 75 62 0f 2f +Decoded freqs 16 (expected 16) +Decoded: 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 1023 Random range test: range 127, max num ARFCNs 29 -Cannot encode range, rc = -1 -Failed on test 0, range 127, num ARFCNs 1 -Cannot encode range, rc = -1 Random range test: range 255, max num ARFCNs 22 -Cannot encode range, rc = -1 -Failed on test 0, range 255, num ARFCNs 1 -Cannot encode range, rc = -1 Random range test: range 511, max num ARFCNs 18 Random range test: range 1023, max num ARFCNs 16 -Cannot encode range, rc = -1 -Failed on test 0, range 1023, num ARFCNs 1 -Cannot encode range, rc = -1 Done. -- 1.7.9.5 From holger at freyther.de Tue Jan 14 16:33:32 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 14 Jan 2014 17:33:32 +0100 Subject: [PATCH 9/9] si: Implement range 128, 256, 1024 encoding In-Reply-To: <1389705863-3730-9-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389705863-3730-9-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140114163332.GC26608@xiaoyu.lan> On Tue, Jan 14, 2014 at 02:24:23PM +0100, Jacob Erlbeck wrote: > This commit adds the implementation of these range formats to the > encoder. In addition, the work-around that tried range 512 first is > removed, so that the selection is primarily based on the max distance > between frequencies. I know you spent a lot of work on separating commits. Somehow I think we can skip the moving of the ARFCN_RANGE_512 code? What do you think? From jerlbeck at sysmocom.de Wed Jan 15 13:15:00 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:15:00 +0100 Subject: [PATCH 9/9] si: Implement range 128, 256, 1024 encoding In-Reply-To: <20140114163332.GC26608@xiaoyu.lan> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389705863-3730-9-git-send-email-jerlbeck@sysmocom.de> <20140114163332.GC26608@xiaoyu.lan> Message-ID: <52D689D4.2010008@sysmocom.de> On 14.01.2014 17:33, Holger Hans Peter Freyther wrote: > I know you spent a lot of work on separating commits. Somehow I think > we can skip the moving of the ARFCN_RANGE_512 code? What do you think? That's ok. I'm going to change that. Jacob From jerlbeck at sysmocom.de Wed Jan 15 13:46:09 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:09 +0100 Subject: [PATCH 1/7] si: Add a config option to disable SI2ter/SI2bis/SI5ter/SI5bis messages In-Reply-To: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> From: Holger Hans Peter Freyther The iPhone5 (US) appears to have some issues with the SIs generated, or the nanoBTS is not sending them correctly. Add a configurable hack to put all bands into the SI2/SI5 message. It is enabled by the bts VTY command 'force-combined-si'. This is a quick change without much reflection and watching for side effects. I have verfied that a network with ARFCN 134 and neighbors ARFCN 130 and 512 do not get generate the SI2ter and announce everything inside the SI2. This patch is based on 'si: Add a hack to disable SI2ter/SI2bis/SI5ter/SI5bis messages'. Ticket: OW#1062 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gsm_data_shared.h | 3 +++ openbsc/src/libbsc/bsc_vty.c | 27 +++++++++++++++++++++++++++ openbsc/src/libbsc/system_information.c | 3 +++ openbsc/tests/vty_test_runner.py | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index b49a539..0922f78 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -670,6 +670,9 @@ struct gsm_bts { int num_trx; struct llist_head trx_list; + /* SI compatibility hacks */ + int force_combined_si; + #ifdef ROLE_BSC /* Abis NM queue */ struct llist_head abis_queue; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 7fa5ea7..4d09e15 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -636,6 +636,9 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) if (bts->excl_from_rf_lock) vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE); + vty_out(vty, " %sforce-combined-si%s", + bts->force_combined_si ? "" : "no ", VTY_NEWLINE); + config_write_bts_model(vty, bts); } @@ -2658,6 +2661,28 @@ DEFUN(cfg_bts_no_excl_rf_lock, return CMD_SUCCESS; } +#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n" + +DEFUN(cfg_bts_force_comb_si, + cfg_bts_force_comb_si_cmd, + "force-combined-si", + FORCE_COMB_SI_STR) +{ + struct gsm_bts *bts = vty->index; + bts->force_combined_si = 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_force_comb_si, + cfg_bts_no_force_comb_si_cmd, + "no force-combined-si", + NO_STR FORCE_COMB_SI_STR) +{ + struct gsm_bts *bts = vty->index; + bts->force_combined_si = 0; + return CMD_SUCCESS; +} + #define TRX_TEXT "Radio Transceiver\n" /* per TRX configuration */ @@ -3255,6 +3280,8 @@ int bsc_vty_init(const struct log_info *cat) install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd); install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd); install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd); + install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd); + install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd); install_element(BTS_NODE, &cfg_trx_cmd); install_node(&trx_node, dummy_config_write); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index c901a4a..5f46bf9 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -72,6 +72,9 @@ static int use_arfcn(const struct gsm_bts *bts, const int bis, const int ter, { if (!bis && !ter && band_compatible(bts, arfcn)) return 1; + if (bts->force_combined_si) + return 0; + /* Correct but somehow broken with either the nanoBTS or the iPhone5 */ if (bis && pgsm && band_compatible(bts, arfcn) && (arfcn < 1 || arfcn > 124)) return 1; if (ter && !band_compatible(bts, arfcn)) diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 16eb213..47e1ad1 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -173,6 +173,24 @@ class TestVTYNITB(TestVTYGenericBSC): self.assertEquals(res.find('periodic location update 60'), -1) self.assert_(res.find('no periodic location update') > 0) + def testEnableDisableSiHacks(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("network") + self.vty.command("bts 0") + + # Enable periodic lu.. + self.vty.verify("force-combined-si", ['']) + res = self.vty.command("write terminal") + self.assert_(res.find(' force-combined-si') > 0) + self.assertEquals(res.find('no force-combined-si'), -1) + + # Now disable it.. + self.vty.verify("no force-combined-si", ['']) + res = self.vty.command("write terminal") + self.assertEquals(res.find(' force-combined-si'), -1) + self.assert_(res.find('no force-combined-si') > 0) + def testRachAccessControlClass(self): self.vty.enable() self.vty.command("configure terminal") -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:10 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:10 +0100 Subject: [PATCH 2/7] si/test: Add tests for range encoding/decoding In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-2-git-send-email-jerlbeck@sysmocom.de> This commit adds test range encoding tests. They check the property decoding(encoding(L)) = L and optionally dump the results and encoded sequences to stdout. There a 2 test modes: - A list of fixed tests - A random number based test loop per ARFCN list size (only dumps the first failing test) Sponsored-by: On-Waves ehf --- openbsc/tests/gsm0408/Makefile.am | 1 + openbsc/tests/gsm0408/gsm0408_test.c | 216 +++++++++++++++++++++++++++++++++ openbsc/tests/gsm0408/gsm0408_test.ok | 48 ++++++++ 3 files changed, 265 insertions(+) diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am index b000c08..1c29ece 100644 --- a/openbsc/tests/gsm0408/Makefile.am +++ b/openbsc/tests/gsm0408/Makefile.am @@ -8,4 +8,5 @@ gsm0408_test_SOURCES = gsm0408_test.c gsm0408_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -ldbi diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 60a151f..721b283 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #define COMPARE(result, op, value) \ if (!((result) op (value))) {\ @@ -94,10 +96,224 @@ static void test_mi_functionality(void) COMPARE_STR(mi_parsed, imsi_even); } +struct { + int range; + int arfcns_num; + int arfcns[RANGE_ENC_MAX_ARFCNS]; +} arfcn_test_ranges[] = { + {ARFCN_RANGE_512, 12, + { 1, 12, 31, 51, 57, 91, 97, 98, 113, 117, 120, 125 }}, + {ARFCN_RANGE_512, 17, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }}, + {ARFCN_RANGE_512, 18, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }}, + {ARFCN_RANGE_512, 18, + { 1, 17, 31, 45, 58, 79, 81, 97, + 113, 127, 213, 277, 287, 311, 331, 391, + 417, 511 }}, + {ARFCN_RANGE_512, 6, + { 1, 17, 31, 45, 58, 79 }}, + {ARFCN_RANGE_512, 6, + { 10, 17, 31, 45, 58, 79 }}, + {ARFCN_RANGE_1024, 17, + { 0, 17, 31, 45, 58, 79, 81, 97, + 113, 127, 213, 277, 287, 311, 331, 391, + 1023 }}, + {ARFCN_RANGE_1024, 16, + { 17, 31, 45, 58, 79, 81, 97, 113, + 127, 213, 277, 287, 311, 331, 391, 1023 }}, + {-1} +}; + +static int test_single_range_encoding(int range, const int *orig_arfcns, + int arfcns_num, int silent) +{ + int arfcns[RANGE_ENC_MAX_ARFCNS]; + int w[RANGE_ENC_MAX_ARFCNS]; + int f0_included = 0; + int rc, f0; + uint8_t chan_list[16] = {0}; + struct gsm_sysinfo_freq dec_freq[1024] = {{0}}; + int dec_arfcns[RANGE_ENC_MAX_ARFCNS] = {0}; + int dec_arfcns_count = 0; + int arfcns_used = 0; + int i; + + arfcns_used = arfcns_num; + memmove(arfcns, orig_arfcns, sizeof(arfcns)); + + f0 = arfcns[0]; + /* + * Manipulate the ARFCN list according to the rules in J4 depending + * on the selected range. + */ + arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + f0, &f0_included); + + memset(w, 0, sizeof(w)); + rc = range_enc_arfcns(range, arfcns, arfcns_used, w, 0); + if (rc != 0) { + printf("Cannot compute range W(k), rc = %d\n", rc); + return 1; + } + + if (!silent) + fprintf(stderr, "range=%d, arfcns_used=%d, f0=%d, f0_included=%d\n", + range, arfcns_used, f0, f0_included); + + /* Select the range and the amount of bits needed */ + switch (range) { + case ARFCN_RANGE_128: + rc = range_enc_range128(chan_list, f0, w); + break; + case ARFCN_RANGE_256: + rc = range_enc_range256(chan_list, f0, w); + break; + case ARFCN_RANGE_512: + rc = range_enc_range512(chan_list, f0, w); + break; + case ARFCN_RANGE_1024: + rc = range_enc_range1024(chan_list, f0, f0_included, w); + break; + default: + return 1; + }; + if (rc != 0) { + printf("Cannot encode range, rc = %d\n", rc); + return 1; + } + + if (!silent) + printf("chan_list = %s\n", + osmo_hexdump(chan_list, sizeof(chan_list))); + + rc = gsm48_decode_freq_list(dec_freq, chan_list, sizeof(chan_list), + 0xfe, 1); + if (rc != 0) { + printf("Cannot decode freq list, rc = %d\n", rc); + return 1; + } + + for (i = 0; i < ARRAY_SIZE(dec_freq); i++) { + if (dec_freq[i].mask && + dec_arfcns_count < ARRAY_SIZE(dec_arfcns)) + dec_arfcns[dec_arfcns_count++] = i; + } + + if (!silent) { + printf("Decoded freqs %d (expected %d)\n", + dec_arfcns_count, arfcns_num); + printf("Decoded: "); + for (i = 0; i < dec_arfcns_count; i++) { + printf("%d ", dec_arfcns[i]); + if (dec_arfcns[i] != orig_arfcns[i]) + printf("(!= %d) ", orig_arfcns[i]); + } + printf("\n"); + } + + if (dec_arfcns_count != arfcns_num) { + printf("Wrong number of arfcns\n"); + return 1; + } + + if (memcmp(dec_arfcns, orig_arfcns, sizeof(dec_arfcns)) != 0) { + printf("Decoding error, got wrong freqs\n"); + fprintf(stderr, " w = "); + for (i = 0; i < ARRAY_SIZE(w); i++) + fprintf(stderr, "%d ", w[i]); + fprintf(stderr, "\n"); + return 1; + } + + return 0; +} + +static void test_random_range_encoding(int range, int max_arfcn_num) +{ + int arfcns_num = 0; + int test_idx; + int rc, max_count; + int num_tests = 1024; + + printf("Random range test: range %d, max num ARFCNs %d\n", + range, max_arfcn_num); + + srandom(1); + + for (max_count = 1; max_count < max_arfcn_num; max_count++) { + for (test_idx = 0; test_idx < num_tests; test_idx++) { + int count; + int i; + int min_freq = 0; + + int rnd_arfcns[RANGE_ENC_MAX_ARFCNS] = {0}; + char rnd_arfcns_set[1024] = {0}; + + if (range < ARFCN_RANGE_1024) + min_freq = random() % (1023 - range); + + for (count = max_count; count; ) { + int arfcn = min_freq + random() % (range + 1); + OSMO_ASSERT(arfcn < ARRAY_SIZE(rnd_arfcns_set)); + + if (!rnd_arfcns_set[arfcn]) { + rnd_arfcns_set[arfcn] = 1; + count -= 1; + } + } + + arfcns_num = 0; + for (i = 0; i < ARRAY_SIZE(rnd_arfcns_set); i++) + if (rnd_arfcns_set[i]) + rnd_arfcns[arfcns_num++] = i; + + rc = test_single_range_encoding(range, rnd_arfcns, + arfcns_num, 1); + if (rc != 0) { + printf("Failed on test %d, range %d, num ARFCNs %d\n", + test_idx, range, max_count); + test_single_range_encoding(range, rnd_arfcns, + arfcns_num, 0); + return; + } + } + } +} + +static void test_range_encoding() +{ + int *arfcns; + int arfcns_num = 0; + int test_idx; + int range; + + for (test_idx = 0; arfcn_test_ranges[test_idx].arfcns_num > 0; test_idx++) + { + arfcns_num = arfcn_test_ranges[test_idx].arfcns_num; + arfcns = &arfcn_test_ranges[test_idx].arfcns[0]; + range = arfcn_test_ranges[test_idx].range; + + printf("Range test %d: range %d, num ARFCNs %d\n", + test_idx, range, arfcns_num); + + test_single_range_encoding(range, arfcns, arfcns_num, 0); + } + + test_random_range_encoding(ARFCN_RANGE_128, 29); + test_random_range_encoding(ARFCN_RANGE_256, 22); + test_random_range_encoding(ARFCN_RANGE_512, 18); + test_random_range_encoding(ARFCN_RANGE_1024, 16); +} + int main(int argc, char **argv) { + osmo_init_logging(&log_info); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + test_location_area_identifier(); test_mi_functionality(); + test_range_encoding(); printf("Done.\n"); return EXIT_SUCCESS; diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index 52c601e..a92b879 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -2,4 +2,52 @@ Testing test location area identifier Testing parsing and generating TMSI/IMSI hex: 17 08 99 78 56 34 12 90 78 36 hex: 17 09 91 78 56 34 12 90 78 56 f4 +Range test 0: range 511, num ARFCNs 12 +chan_list = 88 00 98 34 85 36 7c 50 22 dc 5e ec 00 00 00 00 +Decoded freqs 12 (expected 12) +Decoded: 1 12 31 51 57 91 97 98 113 117 120 125 +Range test 1: range 511, num ARFCNs 17 +chan_list = 88 00 82 7f 01 3f 7e 04 0b ff ff fc 10 41 07 e0 +Decoded freqs 17 (expected 17) +Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +Range test 2: range 511, num ARFCNs 18 +chan_list = 88 00 82 7f 01 7f 7e 04 0b ff ff fc 10 41 07 ff +Decoded freqs 18 (expected 18) +Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +Range test 3: range 511, num ARFCNs 18 +chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 76 +Decoded freqs 18 (expected 18) +Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 507 (!= 511) +Decoding error, got wrong freqs +Range test 4: range 511, num ARFCNs 6 +chan_list = 88 00 8b 3c 88 b9 6b 00 00 00 00 00 00 00 00 00 +Decoded freqs 6 (expected 6) +Decoded: 1 17 31 45 58 79 +Range test 5: range 511, num ARFCNs 6 +chan_list = 88 05 08 fc 88 b9 6b 00 00 00 00 00 00 00 00 00 +Decoded freqs 6 (expected 6) +Decoded: 10 17 31 45 58 79 +Range test 6: range 1023, num ARFCNs 17 +Cannot encode range, rc = -1 +Range test 7: range 1023, num ARFCNs 16 +Cannot encode range, rc = -1 +Random range test: range 127, max num ARFCNs 29 +Cannot encode range, rc = -1 +Failed on test 0, range 127, num ARFCNs 1 +Cannot encode range, rc = -1 +Random range test: range 255, max num ARFCNs 22 +Cannot encode range, rc = -1 +Failed on test 0, range 255, num ARFCNs 1 +Cannot encode range, rc = -1 +Random range test: range 511, max num ARFCNs 18 +Decoding error, got wrong freqs +Failed on test 0, range 511, num ARFCNs 17 +chan_list = 88 21 55 fc da d7 76 03 31 2f ed 45 dc 93 d6 80 +Decoded freqs 17 (expected 17) +Decoded: 66 81 161 250 314 343 383 (!= 380) 395 396 397 409 429 505 506 516 518 545 +Decoding error, got wrong freqs +Random range test: range 1023, max num ARFCNs 16 +Cannot encode range, rc = -1 +Failed on test 0, range 1023, num ARFCNs 1 +Cannot encode range, rc = -1 Done. -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:11 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:11 +0100 Subject: [PATCH 3/7] si/test: Merge si tests into gsm48 tests In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-3-git-send-email-jerlbeck@sysmocom.de> Currently tests covering features of the GSM 04.08 specification are spread over the si and gsm0408 subdirs in tests. This commit merges all tests from 'si' into 'gsm0408' and removes the 'si' test sub-directory. Sponsored-by: On-Waves ehf --- openbsc/configure.ac | 1 - openbsc/tests/Makefile.am | 2 +- openbsc/tests/gsm0408/gsm0408_test.c | 146 ++++++++++++++++++++++++++++++ openbsc/tests/gsm0408/gsm0408_test.ok | 20 +++++ openbsc/tests/si/Makefile.am | 12 --- openbsc/tests/si/si_test.c | 156 --------------------------------- openbsc/tests/si/si_test.ok | 20 ----- openbsc/tests/testsuite.at | 6 -- 8 files changed, 167 insertions(+), 196 deletions(-) delete mode 100644 openbsc/tests/si/Makefile.am delete mode 100644 openbsc/tests/si/si_test.c delete mode 100644 openbsc/tests/si/si_test.ok diff --git a/openbsc/configure.ac b/openbsc/configure.ac index fe99569..5d29af7 100644 --- a/openbsc/configure.ac +++ b/openbsc/configure.ac @@ -166,7 +166,6 @@ AC_OUTPUT( tests/mgcp/Makefile tests/gprs/Makefile tests/gbproxy/Makefile - tests/si/Makefile tests/abis/Makefile tests/smpp/Makefile tests/trau/Makefile diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am index d4bb954..31b2bb4 100644 --- a/openbsc/tests/Makefile.am +++ b/openbsc/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = gsm0408 db channel mgcp gprs si abis gbproxy trau +SUBDIRS = gsm0408 db channel mgcp gprs abis gbproxy trau if BUILD_NAT SUBDIRS += bsc-nat bsc-nat-trie diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 721b283..3a6bbdd 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -42,6 +42,16 @@ exit(-1); \ } +#define DBG(...) + +#define VERIFY(res, cmp, wanted) \ + if (!(res cmp wanted)) { \ + printf("ASSERT failed: %s:%d Wanted: %d %s %d\n", \ + __FILE__, __LINE__, res, # cmp, wanted); \ + } + + + /* * Test Location Area Identifier formatting. Table 10.5.3 of 04.08 */ @@ -306,6 +316,138 @@ static void test_range_encoding() test_random_range_encoding(ARFCN_RANGE_1024, 16); } +static int freqs1[] = { + 12, 70, 121, 190, 250, 320, 401, 475, 520, 574, 634, 700, 764, 830, 905, 980 +}; + +static int freqs2[] = { + 402, 460, 1, 67, 131, 197, 272, 347, +}; + +static int freqs3[] = { + 68, 128, 198, 279, 353, 398, 452, + +}; + +static int w_out[] = { + 122, 2, 69, 204, 75, 66, 60, 70, 83, 3, 24, 67, 54, 64, 70, 9, +}; + +static int range128[] = { + 1, 1 + 127, +}; + +static int range256[] = { + 1, 1 + 128, +}; + +static int range512[] = { + 1, 1+ 511, +}; + + +static void test_arfcn_filter() +{ + int arfcns[50], i, res, f0_included; + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + + /* check that the arfcn is taken out. f0_included is only set for Range1024 */ + f0_included = 24; + res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), + arfcns[0], &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); + VERIFY(f0_included, ==, 0); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); + + /* check with range1024 */ + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), + arfcns[0], &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); + VERIFY(f0_included, ==, 1); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); + + /* check with range1024, not included */ + for (i = 0; i < ARRAY_SIZE(arfcns); ++i) + arfcns[i] = (i + 1) * 2; + res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), + 11, &f0_included); + VERIFY(res, ==, ARRAY_SIZE(arfcns)); + VERIFY(f0_included, ==, 0); + for (i = 0; i < res; ++i) + VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1); +} + +static void test_print_encoding() +{ + int rc; + int w[17]; + uint8_t chan_list[16]; + memset(chan_list, 0x23, sizeof(chan_list)); + + for (rc = 0; rc < ARRAY_SIZE(w); ++rc) + switch (rc % 3) { + case 0: + w[rc] = 0xAAAA; + break; + case 1: + w[rc] = 0x5555; + break; + case 2: + w[rc] = 0x9696; + break; + } + + rc = range_enc_range512(chan_list, (1 << 9) | 0x96, w); + VERIFY(rc, ==, 0); + + printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list))); +} + +static void test_si_range_helpers() +{ + int ws[(sizeof(freqs1)/sizeof(freqs1[0]))]; + int i, f0 = 0xFFFFFF; + + memset(&ws[0], 0x23, sizeof(ws)); + + i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs1[i]); + VERIFY(i, ==, 2); + + i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs2[i]); + VERIFY(i, ==, 2); + + i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3)); + printf("Element is: %d => freqs[i] = %d\n", i, freqs3[i]); + VERIFY(i, ==, 0); + + i = range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0); + VERIFY(i, ==, 0); + + for (i = 0; i < sizeof(freqs1)/sizeof(freqs1[0]); ++i) { + printf("w[%d]=%d\n", i, ws[i]); + VERIFY(ws[i], ==, w_out[i]); + } + + i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); + VERIFY(i, ==, ARFCN_RANGE_128); + VERIFY(f0, ==, 1); + + i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); + VERIFY(i, ==, ARFCN_RANGE_256); + VERIFY(f0, ==, 1); + + i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); + VERIFY(i, ==, ARFCN_RANGE_512); + VERIFY(f0, ==, 1); +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); @@ -313,6 +455,10 @@ int main(int argc, char **argv) test_location_area_identifier(); test_mi_functionality(); + + test_si_range_helpers(); + test_arfcn_filter(); + test_print_encoding(); test_range_encoding(); printf("Done.\n"); diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index a92b879..5458669 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -2,6 +2,26 @@ Testing test location area identifier Testing parsing and generating TMSI/IMSI hex: 17 08 99 78 56 34 12 90 78 36 hex: 17 09 91 78 56 34 12 90 78 56 f4 +Element is: 2 => freqs[i] = 121 +Element is: 2 => freqs[i] = 1 +Element is: 0 => freqs[i] = 68 +w[0]=122 +w[1]=2 +w[2]=69 +w[3]=204 +w[4]=75 +w[5]=66 +w[6]=60 +w[7]=70 +w[8]=83 +w[9]=3 +w[10]=24 +w[11]=67 +w[12]=54 +w[13]=64 +w[14]=70 +w[15]=9 +Range512: 89 4b 2a 95 65 95 55 2c a9 55 aa 55 6a 95 59 55 Range test 0: range 511, num ARFCNs 12 chan_list = 88 00 98 34 85 36 7c 50 22 dc 5e ec 00 00 00 00 Decoded freqs 12 (expected 12) diff --git a/openbsc/tests/si/Makefile.am b/openbsc/tests/si/Makefile.am deleted file mode 100644 index 795bd30..0000000 --- a/openbsc/tests/si/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS) - -EXTRA_DIST = si_test.ok - -noinst_PROGRAMS = si_test - -si_test_SOURCES = si_test.c - -si_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) -lrt $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/openbsc/tests/si/si_test.c b/openbsc/tests/si/si_test.c deleted file mode 100644 index fd840f3..0000000 --- a/openbsc/tests/si/si_test.c +++ /dev/null @@ -1,156 +0,0 @@ - - -#include -#include -#include - -#include - -#include - -#define DBG(...) - -#define VERIFY(res, cmp, wanted) \ - if (!(res cmp wanted)) { \ - printf("ASSERT failed: %s:%d Wanted: %d %s %d\n", \ - __FILE__, __LINE__, res, # cmp, wanted); \ - } - - -static int freqs1[] = { - 12, 70, 121, 190, 250, 320, 401, 475, 520, 574, 634, 700, 764, 830, 905, 980 -}; - -static int freqs2[] = { - 402, 460, 1, 67, 131, 197, 272, 347, -}; - -static int freqs3[] = { - 68, 128, 198, 279, 353, 398, 452, - -}; - -static int w_out[] = { - 122, 2, 69, 204, 75, 66, 60, 70, 83, 3, 24, 67, 54, 64, 70, 9, -}; - -static int range128[] = { - 1, 1 + 127, -}; - -static int range256[] = { - 1, 1 + 128, -}; - -static int range512[] = { - 1, 1+ 511, -}; - - -static void test_arfcn_filter() -{ - int arfcns[50], i, res, f0_included; - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - - /* check that the arfcn is taken out. f0_included is only set for Range1024 */ - f0_included = 24; - res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 0); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); - - /* check with range1024 */ - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 1); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); - - /* check with range1024, not included */ - for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - 11, &f0_included); - VERIFY(res, ==, ARRAY_SIZE(arfcns)); - VERIFY(f0_included, ==, 0); - for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1); -} - -static void test_print_encoding() -{ - int rc; - int w[17]; - uint8_t chan_list[16]; - memset(chan_list, 0x23, sizeof(chan_list)); - - for (rc = 0; rc < ARRAY_SIZE(w); ++rc) - switch (rc % 3) { - case 0: - w[rc] = 0xAAAA; - break; - case 1: - w[rc] = 0x5555; - break; - case 2: - w[rc] = 0x9696; - break; - } - - rc = range_enc_range512(chan_list, (1 << 9) | 0x96, w); - VERIFY(rc, ==, 0); - - printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list))); -} - -int main(int argc, char **argv) -{ - int ws[(sizeof(freqs1)/sizeof(freqs1[0]))]; - int i, f0 = 0xFFFFFF; - - memset(&ws[0], 0x23, sizeof(ws)); - - i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs1[i]); - VERIFY(i, ==, 2); - - i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs2[i]); - VERIFY(i, ==, 2); - - i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs3[i]); - VERIFY(i, ==, 0); - - i = range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0); - VERIFY(i, ==, 0); - - for (i = 0; i < sizeof(freqs1)/sizeof(freqs1[0]); ++i) { - printf("w[%d]=%d\n", i, ws[i]); - VERIFY(ws[i], ==, w_out[i]); - } - - i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0); - VERIFY(i, ==, ARFCN_RANGE_128); - VERIFY(f0, ==, 1); - - i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0); - VERIFY(i, ==, ARFCN_RANGE_256); - VERIFY(f0, ==, 1); - - i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0); - VERIFY(i, ==, ARFCN_RANGE_512); - VERIFY(f0, ==, 1); - - - test_arfcn_filter(); - test_print_encoding(); - - return 0; -} diff --git a/openbsc/tests/si/si_test.ok b/openbsc/tests/si/si_test.ok deleted file mode 100644 index 6a3ee51..0000000 --- a/openbsc/tests/si/si_test.ok +++ /dev/null @@ -1,20 +0,0 @@ -Element is: 2 => freqs[i] = 121 -Element is: 2 => freqs[i] = 1 -Element is: 0 => freqs[i] = 68 -w[0]=122 -w[1]=2 -w[2]=69 -w[3]=204 -w[4]=75 -w[5]=66 -w[6]=60 -w[7]=70 -w[8]=83 -w[9]=3 -w[10]=24 -w[11]=67 -w[12]=54 -w[13]=64 -w[14]=70 -w[15]=9 -Range512: 89 4b 2a 95 65 95 55 2c a9 55 aa 55 6a 95 59 55 diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at index 652cfe9..b2c5518 100644 --- a/openbsc/tests/testsuite.at +++ b/openbsc/tests/testsuite.at @@ -57,12 +57,6 @@ cat $abs_srcdir/bsc-nat-trie/bsc_nat_trie_test.ok > expout AT_CHECK([$abs_top_builddir/tests/bsc-nat-trie/bsc_nat_trie_test], [], [expout], [ignore]) AT_CLEANUP -AT_SETUP([si]) -AT_KEYWORDS([si]) -cat $abs_srcdir/si/si_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/si/si_test], [], [expout], [ignore]) -AT_CLEANUP - AT_SETUP([abis]) AT_KEYWORDS([abis]) cat $abs_srcdir/abis/abis_test.ok > expout -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:12 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:12 +0100 Subject: [PATCH 4/7] si: Fix range512 encoding In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-4-git-send-email-jerlbeck@sysmocom.de> This patch fixes a bug in the range encoder that leads to wrong encoding when 17 or more ARFCNs are encoded. Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 2 +- openbsc/tests/gsm0408/gsm0408_test.ok | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index c52743e..9177546 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -256,7 +256,7 @@ int range_enc_range512(uint8_t *chan_list, int f0, int *w) range512->w15 = HIGH_BITS(w, 15, 6, 6); /* W(16) */ range512->w16_hi = HIGH_BITS(w, 16, 5, 2); - range512->w16_lo = HIGH_BITS(w, 16, 5, 3); + range512->w16_lo = LOW_BITS(w, 16, 5, 3); /* W(17) */ range512->w17 = HIGH_BITS(w, 17, 5, 5); diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index 5458669..dab495d 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -35,10 +35,9 @@ chan_list = 88 00 82 7f 01 7f 7e 04 0b ff ff fc 10 41 07 ff Decoded freqs 18 (expected 18) Decoded: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Range test 3: range 511, num ARFCNs 18 -chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 76 +chan_list = 88 00 94 3a 44 32 d7 2a 43 2a 13 94 e5 38 39 f6 Decoded freqs 18 (expected 18) -Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 507 (!= 511) -Decoding error, got wrong freqs +Decoded: 1 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 417 511 Range test 4: range 511, num ARFCNs 6 chan_list = 88 00 8b 3c 88 b9 6b 00 00 00 00 00 00 00 00 00 Decoded freqs 6 (expected 6) @@ -60,12 +59,6 @@ Cannot encode range, rc = -1 Failed on test 0, range 255, num ARFCNs 1 Cannot encode range, rc = -1 Random range test: range 511, max num ARFCNs 18 -Decoding error, got wrong freqs -Failed on test 0, range 511, num ARFCNs 17 -chan_list = 88 21 55 fc da d7 76 03 31 2f ed 45 dc 93 d6 80 -Decoded freqs 17 (expected 17) -Decoded: 66 81 161 250 314 343 383 (!= 380) 395 396 397 409 429 505 506 516 518 545 -Decoding error, got wrong freqs Random range test: range 1023, max num ARFCNs 16 Cannot encode range, rc = -1 Failed on test 0, range 1023, num ARFCNs 1 -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:13 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:13 +0100 Subject: [PATCH 5/7] si: Fix range1024 encoding In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-5-git-send-email-jerlbeck@sysmocom.de> f0 is currently set to arfcns[0] in range_enc_determine_range(), while GSM 04.08 requires f0 to be ARFCN 0 in range1024 encoding. This patch modifies range_enc_determine_range() to force f0 to be 0 if this encoding is used. This way the case distinction in range_enc_filter_arfcns() is not longer necessary. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/arfcn_range_encode.h | 2 +- openbsc/src/libbsc/arfcn_range_encode.c | 44 +++++++++++--------------- openbsc/src/libbsc/system_information.c | 2 +- openbsc/tests/gsm0408/gsm0408_test.c | 24 +++++++------- 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/openbsc/include/openbsc/arfcn_range_encode.h b/openbsc/include/openbsc/arfcn_range_encode.h index 7a6fff0..bd85d6a 100644 --- a/openbsc/include/openbsc/arfcn_range_encode.h +++ b/openbsc/include/openbsc/arfcn_range_encode.h @@ -16,7 +16,7 @@ enum { int range_enc_determine_range(const int *arfcns, int size, int *f0_out); int range_enc_arfcns(const int rng, const int *arfcns, int sze, int *out, int idx); int range_enc_find_index(const int rng, const int *arfcns, int size); -int range_enc_filter_arfcns(const int rng, int *arfcns, const int sze, const int f0, int *f0_included); +int range_enc_filter_arfcns(int *arfcns, const int sze, const int f0, int *f0_included); int range_enc_range128(uint8_t *chan_list, int f0, int *w); int range_enc_range256(uint8_t *chan_list, int f0, int *w); diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index 9177546..a047a06 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -144,7 +144,9 @@ int range_enc_arfcns(const int range, */ /** * This implements the range determination as described in GSM 04.08 J4. The - * result will be a base frequency f0 and the range to use. + * result will be a base frequency f0 and the range to use. Note that for range + * 1024 encoding f0 always refers to ARFCN 0 even if it is not an element of + * the arfcns list. * * \param[in] arfcns The input frequencies, they must be sorted, lowest number first * \param[in] size The length of the array @@ -166,8 +168,10 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) return ARFCN_RANGE_256; if (max < 512 && size <= 18) return ARFCN_RANGE_512; - if (max < 1024 && size <= 17) + if (max < 1024 && size <= 17) { + *f0 = 0; return ARFCN_RANGE_1024; + } return ARFCN_RANGE_INVALID; } @@ -271,34 +275,24 @@ int range_enc_range1024(uint8_t *chan_list, int f0, int f0_included, int *w) return -1; } -int range_enc_filter_arfcns(const int range, int *arfcns, - const int size, const int f0, int *f0_included) +int range_enc_filter_arfcns(int *arfcns, + const int size, const int f0, int *f0_included) { int i, j = 0; *f0_included = 0; - if (range == ARFCN_RANGE_1024) { - for (i = 0; i < size; ++i) { - if (arfcns[i] == f0) { - *f0_included = 1; - continue; - } - - /* copy and subtract */ - arfcns[j++] = mod(arfcns[i] - 1, 1024); - } - } else { - for (i = 0; i < size; ++i) { - /* - * Appendix J.4 says the following: - * All frequencies except F(0), minus F(0) + 1. - * I assume we need to exclude it here. - */ - if (arfcns[i] == f0) - continue; - - arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); + for (i = 0; i < size; ++i) { + /* + * Appendix J.4 says the following: + * All frequencies except F(0), minus F(0) + 1. + * I assume we need to exclude it here. + */ + if (arfcns[i] == f0) { + *f0_included = 1; + continue; } + + arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); } return j; diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 5f46bf9..95ac736 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -197,7 +197,7 @@ static int enc_freq_lst_range(uint8_t *chan_list, * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 3a6bbdd..894eb0f 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -152,12 +152,12 @@ static int test_single_range_encoding(int range, const int *orig_arfcns, arfcns_used = arfcns_num; memmove(arfcns, orig_arfcns, sizeof(arfcns)); - f0 = arfcns[0]; + f0 = range == ARFCN_RANGE_1024 ? 0 : arfcns[0]; /* * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); @@ -354,28 +354,28 @@ static void test_arfcn_filter() /* check that the arfcn is taken out. f0_included is only set for Range1024 */ f0_included = 24; - res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), arfcns[0], &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 0); + VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); - /* check with range1024 */ + /* check with range1024, ARFCN 0 is included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); + arfcns[i] = i * 2; + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); + VERIFY(arfcns[i], ==, (i + 1) * 2 - 1); - /* check with range1024, not included */ + /* check with range1024, ARFCN 0 not included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - 11, &f0_included); + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns)); VERIFY(f0_included, ==, 0); for (i = 0; i < res; ++i) -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:14 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:14 +0100 Subject: [PATCH 6/7] si: Add generic range w(k) encoder In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-6-git-send-email-jerlbeck@sysmocom.de> Currently the encoding of the chan_list is done by a hard-coded sequence of macros that closely resembles figure 10.5.16 in 3GPP TS 04.08. This patch replaces this by an algorithmic solution that can be used for all range encodings and is based on the property W(2^i) to W(2^(i+1)-1) are on w1_len-i bits when present (see section 10.5.2.13 in TS 04.08). Ticket: OW#1061 Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 141 ++++++++++++++++++------------- 1 file changed, 83 insertions(+), 58 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index a047a06..1a26523 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -176,16 +176,6 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) return ARFCN_RANGE_INVALID; } -/* - * The below is easier is to write in four methods than - * to use the max_bits. The encoding is so screwed.. as - * the bits need to be put in place in the wrong order.. - */ -#define HIGH_BITS(w, index, bits, offset) \ - (w[index - 1] >> (bits - offset)) -#define LOW_BITS(w, index, bits, offset) \ - (w[index - 1]) - static void write_orig_arfcn(uint8_t *chan_list, int f0) { chan_list[0] |= (f0 >> 9) & 1; @@ -193,6 +183,88 @@ static void write_orig_arfcn(uint8_t *chan_list, int f0) chan_list[2] = (f0 & 1) << 7; } +static void write_all_wn(uint8_t *chan_list, int bit_offs, + int *w, int w_size, int w1_len) +{ + int octet_offs = 0; /* offset into chan_list */ + int wk_len = w1_len; /* encoding size in bits of w[k] */ + int k; /* 1 based */ + int level = 0; /* tree level, top level = 0 */ + int lvl_left = 1; /* nodes per tree level */ + + /* W(2^i) to W(2^(i+1)-1) are on w1_len-i bits when present */ + + for (k = 1; k <= w_size; k++) { + int wk_left = wk_len; + DEBUGP(DRR, + "k=%d, wk_len=%d, offs=%d:%d, level=%d, " + "lvl_left=%d\n", + k, wk_len, octet_offs, bit_offs, level, lvl_left); + + while (wk_left > 0) { + int cur_bits = 8 - bit_offs; + int cur_mask; + int wk_slice; + + if (cur_bits > wk_left) + cur_bits = wk_left; + + cur_mask = ((1 << cur_bits) - 1); + + DEBUGP(DRR, + " wk_left=%d, cur_bits=%d, offs=%d:%d\n", + wk_left, cur_bits, octet_offs, bit_offs); + + /* advance */ + wk_left -= cur_bits; + bit_offs += cur_bits; + + /* right aligned wk data for current out octet */ + wk_slice = (w[k-1] >> wk_left) & cur_mask; + + /* cur_bits now contains the number of bits + * that are to be copied from wk to the chan_list. + * wk_left is set to the number of bits that must + * not yet be copied. + * bit_offs points after the bit area that is going to + * be overwritten: + * + * wk_left + * | + * v + * wk: WWWWWWWWWWW + * |||||<-- wk_slice, cur_bits=5 + * --WWWWW- + * ^ + * | + * bit_offs + */ + + DEBUGP(DRR, + " wk=%02x, slice=%02x/%02x, cl=%02x\n", + w[k-1], wk_slice, cur_mask, wk_slice << (8 - bit_offs)); + + chan_list[octet_offs] &= ~(cur_mask << (8 - bit_offs)); + chan_list[octet_offs] |= wk_slice << (8 - bit_offs); + + /* adjust output */ + if (bit_offs == 8) { + bit_offs = 0; + octet_offs += 1; + } + } + + /* adjust bit sizes */ + lvl_left -= 1; + if (!lvl_left) { + /* completed tree level, advance to next */ + level += 1; + lvl_left = 1 << level; + wk_len -= 1; + } + } +} + int range_enc_range128(uint8_t *chan_list, int f0, int *w) { chan_list[0] = 0x8C; @@ -213,57 +285,10 @@ int range_enc_range256(uint8_t *chan_list, int f0, int *w) int range_enc_range512(uint8_t *chan_list, int f0, int *w) { - struct gsm48_range_512 *range512; chan_list[0] = 0x88; write_orig_arfcn(chan_list, f0); - range512 = (struct gsm48_range_512 *) &chan_list[0]; - - /* W(1) */ - range512->w1_hi = HIGH_BITS(w, 1, 9, 7); - range512->w1_lo = LOW_BITS (w, 1, 9, 2); - /* W(2) */ - range512->w2_hi = HIGH_BITS(w, 2, 8, 6); - range512->w2_lo = LOW_BITS (w, 2, 8, 2); - /* W(3) */ - range512->w3_hi = HIGH_BITS(w, 3, 8, 6); - range512->w3_lo = LOW_BITS (w, 3, 8, 2); - /* W(4) */ - range512->w4_hi = HIGH_BITS(w, 4, 7, 6); - range512->w4_lo = LOW_BITS (w, 4, 7, 1); - /* W(5) */ - range512->w5 = HIGH_BITS(w, 5, 7, 7); - /* W(6) */ - range512->w6 = HIGH_BITS(w, 6, 7, 7); - /* W(7) */ - range512->w7_hi = HIGH_BITS(w, 7, 7, 1); - range512->w7_lo = LOW_BITS (w, 7, 7, 6); - /* W(8) */ - range512->w8_hi = HIGH_BITS(w, 8, 6, 2); - range512->w8_lo = LOW_BITS (w, 8, 6, 4); - /* W(9) */ - range512->w9_hi = HIGH_BITS(w, 9, 6, 4); - range512->w9_lo = LOW_BITS(w, 9, 6, 2); - /* W(10) */ - range512->w10 = HIGH_BITS(w, 10, 6, 6); - /* W(11) */ - range512->w11 = HIGH_BITS(w, 11, 6, 6); - /* W(12) */ - range512->w12_hi = HIGH_BITS(w, 12, 6, 2); - range512->w12_lo = LOW_BITS (w, 12, 6, 4); - /* W(13) */ - range512->w13_hi = HIGH_BITS(w, 13, 6, 4); - range512->w13_lo = LOW_BITS(w, 13, 6, 2); - /* W(14) */ - range512->w14 = HIGH_BITS(w, 14, 6, 6); - /* W(15) */ - range512->w15 = HIGH_BITS(w, 15, 6, 6); - /* W(16) */ - range512->w16_hi = HIGH_BITS(w, 16, 5, 2); - range512->w16_lo = LOW_BITS(w, 16, 5, 3); - /* W(17) */ - range512->w17 = HIGH_BITS(w, 17, 5, 5); - + write_all_wn(&chan_list[2], 1, w, 17, 9); return 0; } -- 1.7.9.5 From jerlbeck at sysmocom.de Wed Jan 15 13:46:15 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 15 Jan 2014 14:46:15 +0100 Subject: [PATCH 7/7] si: Implement range 128, 256, 1024 encoding In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389793575-11180-7-git-send-email-jerlbeck@sysmocom.de> This commit adds the implementation of these range formats to the encoder. In addition, the work-around that tried range 512 first is removed, so that the selection is primarily based on the max distance between frequencies. Ticket: OW#1061 Sponsored-by: On-Waves ehf --- openbsc/src/libbsc/arfcn_range_encode.c | 12 ++++++------ openbsc/tests/gsm0408/gsm0408_test.ok | 17 ++++++----------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index 1a26523..e67bf0a 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -270,8 +270,8 @@ int range_enc_range128(uint8_t *chan_list, int f0, int *w) chan_list[0] = 0x8C; write_orig_arfcn(chan_list, f0); - LOGP(DRR, LOGL_ERROR, "Range128 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[2], 1, w, 28, 7); + return 0; } int range_enc_range256(uint8_t *chan_list, int f0, int *w) @@ -279,8 +279,8 @@ int range_enc_range256(uint8_t *chan_list, int f0, int *w) chan_list[0] = 0x8A; write_orig_arfcn(chan_list, f0); - LOGP(DRR, LOGL_ERROR, "Range256 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[2], 1, w, 21, 8); + return 0; } int range_enc_range512(uint8_t *chan_list, int f0, int *w) @@ -296,8 +296,8 @@ int range_enc_range1024(uint8_t *chan_list, int f0, int f0_included, int *w) { chan_list[0] = 0x80 | (f0_included << 2); - LOGP(DRR, LOGL_ERROR, "Range1024 encoding is not implemented.\n"); - return -1; + write_all_wn(&chan_list[0], 6, w, 16, 10); + return 0; } int range_enc_filter_arfcns(int *arfcns, diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index dab495d..3d3c4e6 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -47,20 +47,15 @@ chan_list = 88 05 08 fc 88 b9 6b 00 00 00 00 00 00 00 00 00 Decoded freqs 6 (expected 6) Decoded: 10 17 31 45 58 79 Range test 6: range 1023, num ARFCNs 17 -Cannot encode range, rc = -1 +chan_list = 84 71 e4 ab b9 58 05 cb 39 17 fd b0 75 62 0f 2f +Decoded freqs 17 (expected 17) +Decoded: 0 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 1023 Range test 7: range 1023, num ARFCNs 16 -Cannot encode range, rc = -1 +chan_list = 80 71 e4 ab b9 58 05 cb 39 17 fd b0 75 62 0f 2f +Decoded freqs 16 (expected 16) +Decoded: 17 31 45 58 79 81 97 113 127 213 277 287 311 331 391 1023 Random range test: range 127, max num ARFCNs 29 -Cannot encode range, rc = -1 -Failed on test 0, range 127, num ARFCNs 1 -Cannot encode range, rc = -1 Random range test: range 255, max num ARFCNs 22 -Cannot encode range, rc = -1 -Failed on test 0, range 255, num ARFCNs 1 -Cannot encode range, rc = -1 Random range test: range 511, max num ARFCNs 18 Random range test: range 1023, max num ARFCNs 16 -Cannot encode range, rc = -1 -Failed on test 0, range 1023, num ARFCNs 1 -Cannot encode range, rc = -1 Done. -- 1.7.9.5 From holger at freyther.de Wed Jan 15 16:45:10 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 15 Jan 2014 17:45:10 +0100 Subject: [PATCH 1/7] si: Add a config option to disable SI2ter/SI2bis/SI5ter/SI5bis messages In-Reply-To: <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> References: <1389705863-3730-1-git-send-email-jerlbeck@sysmocom.de> <1389793575-11180-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140115164510.GG18114@xiaoyu.lan> On Wed, Jan 15, 2014 at 02:46:09PM +0100, Jacob Erlbeck wrote: > From: Holger Hans Peter Freyther Dear Jacob, small technical issue. These patches appear to depend on your MGCP work and I can't git am them right now (and -3 doesn't work due the missing old parent). Could you please publish your MGCP and SI branch? I will merge them then. holger From holger at freyther.de Thu Jan 16 10:25:52 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 16 Jan 2014 11:25:52 +0100 Subject: Feedback on l1sap-parts Message-ID: <20140116102552.GL18114@xiaoyu.lan> Dear Andreas, I noticed you rebased the code and I have further comments and requests for general changes. Magic Numbers: Please avoid magic numbers where you can. There is no runtime overhead by using a define and little pre-processing overhead. E.g. in here #define L1SAP_IS_LINK_SACCH(link_id) ((link_id & 0xC0) == 0x40) Make your methods smaller: Please compare this with the work Daniel and me to in cleaning up your code in the osmo-pcu. By splitting up the alloc_algorithm_b code we started to notice various defects just by looking at the code. Remove copy and paste: I think I saw the msgb in-place changing in at least two places. Avoid copy and paste (code cloning). Avoid putting logic in deeply nested constructs: if (a) if (b) if (c) important_stuff kind regards holger From andreas at eversberg.eu Thu Jan 16 15:38:17 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 16 Jan 2014 16:38:17 +0100 Subject: Feedback on l1sap-parts In-Reply-To: <20140116102552.GL18114@xiaoyu.lan> References: <20140116102552.GL18114@xiaoyu.lan> Message-ID: <52D7FCE9.5020709@eversberg.eu> Holger Hans Peter Freyther wrote: dear holger, thanks for advices. > E.g. in here > #define L1SAP_IS_LINK_SACCH(link_id) ((link_id & 0xC0) == 0x40) > i could change it (and other defines) to something like #define GSM_LINK_ID_SACCH 0x40 #define GSM_LINK_ID_MASK 0xc0 #define L1SAP_IS_LINK_SACCH(link_id) ((link_id & GSM_LINK_ID_MASK) == GSM_LINK_ID_SACCH) is that what you mean by avoiding magic numbers? best regards, andreas From jolly at eversberg.eu Thu Jan 16 15:04:12 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Thu, 16 Jan 2014 16:04:12 +0100 Subject: [PATCH] Remove obsolete check of conn and lchan pointers not beeing NULL Message-ID: <1389884652-10758-1-git-send-email-jolly@eversberg.eu> The check is removed from gsm48_cc_rx_setup() and gsm48_cc_rx_call_conf(). Receiving a layer 3 message implies that the transaction has a subscriber connection and a logical channel. This patch fixes the Coverity issues with CID 115311 and CID 1155312. --- openbsc/src/libmsc/gsm_04_08.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 54f5f70..0c6b100 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1803,8 +1803,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) memset(&setup, 0, sizeof(struct gsm_mncc)); setup.callref = trans->callref; - if (trans->conn && trans->conn->lchan) - setup.lchan_type = trans->conn->lchan->type; + setup.lchan_type = trans->conn->lchan->type; tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* emergency setup is identified by msg_type */ if (msg_type == GSM48_MT_CC_EMERG_SETUP) @@ -1961,8 +1960,7 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) memset(&call_conf, 0, sizeof(struct gsm_mncc)); call_conf.callref = trans->callref; - if (trans->conn && trans->conn->lchan) - call_conf.lchan_type = trans->conn->lchan->type; + call_conf.lchan_type = trans->conn->lchan->type; tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); #if 0 /* repeat */ -- 1.7.3.4 From jerlbeck at sysmocom.de Thu Jan 16 15:50:39 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 16 Jan 2014 16:50:39 +0100 Subject: [PATCH 1/3] mgcp: Disable output enabled on initialisation Message-ID: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> Currently RTP output_enabled is set to 1 on initialisation, which does not semantically match the initial value of conn_mode (MGCP_CONN_NONE). This patch changes this initial value to 0. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 2 +- openbsc/tests/mgcp/mgcp_test.ok | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 9996ba7..9055bdb 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -1258,7 +1258,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->frames_per_packet = 0; /* unknown */ end->packet_duration_ms = DEFAULT_RTP_AUDIO_PACKET_DURATION_MS; end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; - end->output_enabled = 1; + end->output_enabled = 0; } static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 7e8aa5c..3b645e6 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -51,7 +51,7 @@ Connection mode: 2, BTS output disabled, NET output enabled Testing DLCX Detected packet duration: 20 Requested packetization period not set -Connection mode: 0, BTS output enabled, NET output enabled +Connection mode: 0, BTS output disabled, NET output disabled Testing CRCX_ZYN Dummy packets: 1 Packet duration not set @@ -67,7 +67,7 @@ Testing RQNT2 Testing DLCX Detected packet duration: 20 Requested packetization period not set -Connection mode: 0, BTS output enabled, NET output enabled +Connection mode: 0, BTS output disabled, NET output disabled Testing CRCX Re-transmitting CRCX Testing RQNT1 -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 16 15:50:40 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 16 Jan 2014 16:50:40 +0100 Subject: [PATCH 2/3] mgcp: Synchronize conn mode bits and output enabled flags In-Reply-To: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> References: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389887441-15344-2-git-send-email-jerlbeck@sysmocom.de> This patch changes implementation and the mgcp_connection_mode enum in a way that net_end.output_enabled (bts_end.output_enabled) flag always matches the MGCP_CONN_SEND_ONLY (MGCP_CONN_RECV_ONLY) bit of conn_mode. Based on this, the conn_mode bits are then used instead of the output_enabled fields within mgcp_protocol.c. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 2 +- openbsc/src/libmgcp/mgcp_protocol.c | 31 +++++++---------------------- openbsc/tests/mgcp/mgcp_test.c | 33 ++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index b4899e4..28ea678 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -32,7 +32,7 @@ enum mgcp_connection_mode { MGCP_CONN_RECV_ONLY = 1, MGCP_CONN_SEND_ONLY = 2, MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY, - MGCP_CONN_LOOPBACK = 4, + MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND, }; enum mgcp_trunk_type { diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 9055bdb..5c88c9d 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -504,28 +504,10 @@ static int parse_conn_mode(const char *msg, struct mgcp_endpoint *endp) ret = -1; } - switch (endp->conn_mode) { - case MGCP_CONN_NONE: - endp->net_end.output_enabled = 0; - endp->bts_end.output_enabled = 0; - break; - - case MGCP_CONN_RECV_ONLY: - endp->net_end.output_enabled = 0; - endp->bts_end.output_enabled = 1; - break; - - case MGCP_CONN_SEND_ONLY: - endp->net_end.output_enabled = 1; - endp->bts_end.output_enabled = 0; - break; - - default: - endp->net_end.output_enabled = 1; - endp->bts_end.output_enabled = 1; - break; - } - + endp->net_end.output_enabled = + endp->conn_mode & MGCP_CONN_SEND_ONLY ? 1 : 0; + endp->bts_end.output_enabled = + endp->conn_mode & MGCP_CONN_RECV_ONLY ? 1 : 0; return ret; } @@ -877,7 +859,7 @@ mgcp_header_done: if (p->cfg->change_cb) p->cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX); - if (endp->bts_end.output_enabled && tcfg->keepalive_interval != 0) + if (endp->conn_mode & MGCP_CONN_RECV_ONLY && tcfg->keepalive_interval != 0) mgcp_send_dummy(endp); create_transcoder(endp); @@ -979,7 +961,8 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) if (p->cfg->change_cb) p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX); - if (endp->bts_end.output_enabled && endp->tcfg->keepalive_interval != 0) + if (endp->conn_mode & MGCP_CONN_RECV_ONLY && + endp->tcfg->keepalive_interval != 0) mgcp_send_dummy(endp); if (silent) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 7eeef99..1f11b1d 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -321,6 +321,19 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); } +#define CONN_UNMODIFIED (0x1000) + +static void test_values(void) +{ + /* Check that NONE disables all output */ + OSMO_ASSERT((MGCP_CONN_NONE & MGCP_CONN_RECV_SEND) == 0) + + /* Check that LOOPBACK enables all output */ + OSMO_ASSERT((MGCP_CONN_LOOPBACK & MGCP_CONN_RECV_SEND) == + MGCP_CONN_RECV_SEND) +} + + static void test_messages(void) { struct mgcp_config *cfg; @@ -341,9 +354,9 @@ static void test_messages(void) endp = &cfg->trunk.endpoints[i]; endp->net_end.payload_type = PTYPE_NONE; endp->net_end.packet_duration_ms = -1; - endp->bts_end.output_enabled = 0; - endp->net_end.output_enabled = 0; - endp->conn_mode = -1; + + OSMO_ASSERT(endp->conn_mode == MGCP_CONN_NONE); + endp->conn_mode |= CONN_UNMODIFIED; } for (i = 0; i < ARRAY_SIZE(tests); i++) { @@ -386,7 +399,7 @@ static void test_messages(void) else printf("Requested packetization period not set\n"); - if (endp->conn_mode != -1) + if ((endp->conn_mode & CONN_UNMODIFIED) == 0) printf("Connection mode: %d, " "BTS output %sabled, NET output %sabled\n", endp->conn_mode, @@ -395,12 +408,17 @@ static void test_messages(void) else printf("Connection mode not set\n"); + OSMO_ASSERT(endp->net_end.output_enabled == + (endp->conn_mode & MGCP_CONN_SEND_ONLY ? 1 : 0)); + OSMO_ASSERT(endp->bts_end.output_enabled == + (endp->conn_mode & MGCP_CONN_RECV_ONLY ? 1 : 0)); + endp->net_end.packet_duration_ms = -1; - endp->bts_end.output_enabled = 0; - endp->net_end.output_enabled = 0; endp->local_options.pkt_period_min = 0; endp->local_options.pkt_period_max = 0; - endp->conn_mode = -1; + endp->conn_mode = MGCP_CONN_NONE | CONN_UNMODIFIED; + endp->net_end.output_enabled = 0; + endp->bts_end.output_enabled = 0; } @@ -784,6 +802,7 @@ int main(int argc, char **argv) osmo_init_logging(&log_info); test_strline(); + test_values(); test_messages(); test_retransmission(); test_packet_loss_calc(); -- 1.7.9.5 From holger at freyther.de Mon Jan 20 07:18:00 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 08:18:00 +0100 Subject: [PATCH 2/3] mgcp: Synchronize conn mode bits and output enabled flags In-Reply-To: <1389887441-15344-2-git-send-email-jerlbeck@sysmocom.de> References: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> <1389887441-15344-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140120071800.GE27930@xiaoyu.lan> On Thu, Jan 16, 2014 at 04:50:40PM +0100, Jacob Erlbeck wrote: Good Morning! > +#define CONN_UNMODIFIED (0x1000) > + > +static void test_values(void) > +{ > + /* Check that NONE disables all output */ > + OSMO_ASSERT((MGCP_CONN_NONE & MGCP_CONN_RECV_SEND) == 0) > + > + /* Check that LOOPBACK enables all output */ > + OSMO_ASSERT((MGCP_CONN_LOOPBACK & MGCP_CONN_RECV_SEND) == > + MGCP_CONN_RECV_SEND) > +} I think osmo_static_assert would work here too? I am applying your patches as is though. > - if (endp->conn_mode != -1) > + if ((endp->conn_mode & CONN_UNMODIFIED) == 0) > printf("Connection mode: %d, " > "BTS output %sabled, NET output %sabled\n", > endp->conn_mode, In the next step we could change the test output to illustrate the tri-state from on/off and not modified to previous test? > + endp->conn_mode = MGCP_CONN_NONE | CONN_UNMODIFIED; > + endp->net_end.output_enabled = 0; > + endp->bts_end.output_enabled = 0; do we still need these flags? Or only because of the above printf? From jerlbeck at sysmocom.de Mon Jan 20 07:50:35 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 20 Jan 2014 08:50:35 +0100 Subject: [PATCH 2/3] mgcp: Synchronize conn mode bits and output enabled flags In-Reply-To: <20140120071800.GE27930@xiaoyu.lan> References: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> <1389887441-15344-2-git-send-email-jerlbeck@sysmocom.de> <20140120071800.GE27930@xiaoyu.lan> Message-ID: <52DCD54B.9030807@sysmocom.de> Hi On 20.01.2014 08:18, Holger Hans Peter Freyther wrote: > On Thu, Jan 16, 2014 at 04:50:40PM +0100, Jacob Erlbeck wrote: >>> + /* Check that LOOPBACK enables all output */ >> + OSMO_ASSERT((MGCP_CONN_LOOPBACK & MGCP_CONN_RECV_SEND) == >> + MGCP_CONN_RECV_SEND) > > I think osmo_static_assert would work here too? Yes, it would. > >> - if (endp->conn_mode != -1) >> + if ((endp->conn_mode & CONN_UNMODIFIED) == 0) >> printf("Connection mode: %d, " >> "BTS output %sabled, NET output %sabled\n", >> endp->conn_mode, > > In the next step we could change the test output to illustrate the > tri-state from on/off and not modified to previous test? Ok, I'd print the output_enabled values to stderr then. > >> + endp->conn_mode = MGCP_CONN_NONE | CONN_UNMODIFIED; >> + endp->net_end.output_enabled = 0; >> + endp->bts_end.output_enabled = 0; > > do we still need these flags? Or only because of the above printf? Yes, we do. Since conn_mode (the SEND_RECV bits) is modified, the output_enabled must be adjusted, so that the invariant holds (this is the central topic of this patch). I didn't want to have a modified behaviour of the test, since this ought to be a semantic-neutral modification (ideally with a unmodified ok file). See the next patch "mgcp/test: Don't reset conn_mode between messages", that addresses this issue. Jacob > > From jerlbeck at sysmocom.de Thu Jan 16 15:50:41 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 16 Jan 2014 16:50:41 +0100 Subject: [PATCH 3/3] mgcp/test: Don't reset conn_mode between messages In-Reply-To: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> References: <1389887441-15344-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1389887441-15344-3-git-send-email-jerlbeck@sysmocom.de> Currently, the conn_mode field is reset after it has been checked. This patch disables this behaviour and only adds a mark (bit) to detect modifications. Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 4 +--- openbsc/tests/mgcp/mgcp_test.ok | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 1f11b1d..fa68867 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -416,9 +416,7 @@ static void test_messages(void) endp->net_end.packet_duration_ms = -1; endp->local_options.pkt_period_min = 0; endp->local_options.pkt_period_max = 0; - endp->conn_mode = MGCP_CONN_NONE | CONN_UNMODIFIED; - endp->net_end.output_enabled = 0; - endp->bts_end.output_enabled = 0; + endp->conn_mode |= CONN_UNMODIFIED; } diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 3b645e6..fbe2566 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -21,6 +21,7 @@ Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 1, BTS output enabled, NET output disabled Testing MDCX3 +Dummy packets: 1 Packet duration not set Requested packetization period not set Connection mode not set -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Jan 17 08:22:57 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 17 Jan 2014 09:22:57 +0100 Subject: [PATCH] openbsc: Fix coverity issues Message-ID: <1389946977-25318-1-git-send-email-jerlbeck@sysmocom.de> This patch (hopefully) fixes the new defects reported by coverity. Addresses: ** CID 1156986: Negative array index read (NEGATIVE_RETURNS) /tests/gsm0408/gsm0408_test.c: 419 in test_si_range_helpers() /tests/gsm0408/gsm0408_test.c: 423 in test_si_range_helpers() /tests/gsm0408/gsm0408_test.c: 427 in test_si_range_helpers() ** CID 1156987: Unchecked return value from library (CHECKED_RETURN) /src/libmgcp/mgcp_protocol.c: 1150 in mgcp_keepalive_timer_cb() ** CID 1156988: Unchecked return value from library (CHECKED_RETURN) /src/libmgcp/mgcp_protocol.c: 983 in handle_modify_con() Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 19 ++++++++++++++++--- openbsc/tests/gsm0408/gsm0408_test.c | 6 +++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 0cc2041..b55ac04 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -134,11 +134,24 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) rc = mgcp_udp_send(endp->net_end.rtp.fd, &endp->net_end.addr, endp->net_end.rtp_port, buf, 1); - if (rc == -1 || endp->tcfg->omit_rtcp) + if (rc == -1) + goto failed; + + if (endp->tcfg->omit_rtcp) + return rc; + + rc = mgcp_udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr, + endp->net_end.rtcp_port, buf, 1); + + if (rc >= 0) return rc; - return mgcp_udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr, - endp->net_end.rtcp_port, buf, 1); +failed: + LOGP(DMGCP, LOGL_ERROR, + "Failed to send dummy packet: %s on: 0x%x to %s\n", + strerror(errno), ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr)); + + return -1; } static int32_t compute_timestamp_aligment_error(struct mgcp_rtp_stream_state *sstate, diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 894eb0f..38c1a6a 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -416,15 +416,15 @@ static void test_si_range_helpers() memset(&ws[0], 0x23, sizeof(ws)); i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs1[i]); + printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs1[i] : -1); VERIFY(i, ==, 2); i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs2[i]); + printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs2[i] : -1); VERIFY(i, ==, 2); i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3)); - printf("Element is: %d => freqs[i] = %d\n", i, freqs3[i]); + printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs3[i] : -1); VERIFY(i, ==, 0); i = range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0); -- 1.7.9.5 From holger at freyther.de Fri Jan 17 13:57:11 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 17 Jan 2014 14:57:11 +0100 Subject: Control interface and counters Message-ID: <20140117135711.GW18114@xiaoyu.lan> Dear Ivan, I noticed that you added a lot of commands to query counters. When we are designing the interface we made sure to add wildcard commands. So most counters can be already read without adding a special command for that. holger From Ivan.Kluchnikov at fairwaves.ru Fri Jan 24 15:01:57 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Fri, 24 Jan 2014 19:01:57 +0400 Subject: Control interface and counters In-Reply-To: <20140117135711.GW18114@xiaoyu.lan> References: <20140117135711.GW18114@xiaoyu.lan> Message-ID: Hi Holger, Thank you for advice. Can you give me example? Which command I should use to read counters? I can't find any documentation for these commands. 2014/1/17 Holger Hans Peter Freyther : > Dear Ivan, > > I noticed that you added a lot of commands to query counters. When > we are designing the interface we made sure to add wildcard commands. > So most counters can be already read without adding a special command > for that. > > holger > > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From holger at freyther.de Sat Jan 25 21:08:39 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 25 Jan 2014 22:08:39 +0100 Subject: Control interface and counters In-Reply-To: References: <20140117135711.GW18114@xiaoyu.lan> Message-ID: <20140125210839.GK9524@xiaoyu.lan> On Fri, Jan 24, 2014 at 07:01:57PM +0400, Ivan Kluchnikov wrote: > Hi Holger, Dear Ivan, > Thank you for advice. > Can you give me example? > Which command I should use to read counters? > I can't find any documentation for these commands. Please take a look at libctrl/control_if.c and search for counter. When we were designing the control interface we really didn't want to write one command per counter. So there is a command installed for "counter *" and "rate_ctr *". This gives access to all counters by name. E.g. using the example script we wrote you can do: $ ./contrib/bsc_control.py -g counter.net.paging.expired -p 4249 -d localhost Got message: GET_REPLY 1 counter.net.paging.expired 0 What is missing from the control interface is for a command to describe itself. Maybe you have the time to implement this feature? The output could be similar to the XML generated by the VTY. A command could have an additional function to describe itself, the parameters and such. holger From dwillmann at sysmocom.de Fri Jan 17 16:26:25 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Fri, 17 Jan 2014 17:26:25 +0100 Subject: SMPP fixes Message-ID: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> Hello, I have found a couple bugs in the read callback of smpp_smsc.c with regards to guarding against malformed packets. Please see attached patches for fixes. They are also published in openbsc branch daniel/smpp-fixes Regarding the last fix I don't think it is necessary to receive messages up to SSIZE_MAX, but since I don't have/know a value for the maximum sensible size I left it like that for 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 dwillmann at sysmocom.de Fri Jan 17 16:26:26 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Fri, 17 Jan 2014 17:26:26 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> Message-ID: Read returning -1 is an error here so make sure and print the actual reason and close the socket. Otherwise we just loop over the fd with read returning -1 every time. EINTR is handled to not cause an error and because the socket is not opened with O_NONBLOCK we don't need to check EAGAIN/EWOULDBLOCK. --- openbsc/src/libmsc/smpp_smsc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index 64ed200..943464f 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -778,8 +778,12 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = sizeof(uint32_t) - esme->read_idx; rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); + /* EINTR is a non-fatal error, just try again */ + if (errno == EINTR) + return 0; + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + esme->system_id, rc, strerror(errno)); + goto dead_socket; } else if (rc == 0) { goto dead_socket; } else @@ -801,8 +805,9 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + esme->system_id, rc, strerror(errno)); + goto dead_socket; } else if (rc == 0) { goto dead_socket; } else { -- 1.8.4.2 From dwillmann at sysmocom.de Fri Jan 17 16:26:27 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Fri, 17 Jan 2014 17:26:27 +0100 Subject: [PATCH 2/3] smpp_smsc: Check that the size is large enough to hold actual data In-Reply-To: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> Message-ID: The first four bytes are the length including the length field. For length < 4 the subsequent msgb_put(msg, sizeof(uint32_t)) will fail, resulting in an abort. This patch guards against this problem by closing the connection if the length received is < 5 (since no payload does not make any sense). The issue is reproducible with: echo -e "\x00\x00\x00\x02\x00" |socat stdin tcp:localhost:2775 --- openbsc/src/libmsc/smpp_smsc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index 943464f..a3dc311 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -790,6 +790,12 @@ static int esme_link_read_cb(struct osmo_fd *ofd) esme->read_idx += rc; if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); + if (esme->read_len <= 4) { + LOGP(DSMPP, LOGL_ERROR, "[%s] read length too small %d\n", + esme->system_id, esme->read_len); + goto dead_socket; + } + msg = msgb_alloc(esme->read_len, "SMPP Rx"); if (!msg) return -ENOMEM; -- 1.8.4.2 From dwillmann at sysmocom.de Fri Jan 17 16:26:28 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Fri, 17 Jan 2014 17:26:28 +0100 Subject: [PATCH 3/3] smpp_smsc: Fix 32-bit signed integer overflow in read return value In-Reply-To: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <50e0df3cabf635e920a2b913eb0dd689bf63e6f3.1389975043.git.daniel@totalueberwachung.de> In case the length is 2^31+4 or larger we compute a negative value to read in rdlen (since it is a signed int). This results in read failing with EFAULT. This patch changes the type of rdlen and rc to ssize_t (the return value of read) and guards against the read length being larger than (SSIZE_MAX). To reproduce the issue run: echo -e "\x80\x00\x00\x05\x00" |socat stdin tcp:localhost:2775 --- openbsc/src/libmsc/smpp_smsc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index a3dc311..23acfc2 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -770,8 +771,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) uint8_t *lenptr = (uint8_t *) &len; uint8_t *cur; struct msgb *msg; - int rdlen; - int rc; + ssize_t rdlen, rc; switch (esme->read_state) { case READ_ST_IN_LEN: @@ -781,7 +781,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) /* EINTR is a non-fatal error, just try again */ if (errno == EINTR) return 0; - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", esme->system_id, rc, strerror(errno)); goto dead_socket; } else if (rc == 0) { @@ -790,8 +790,8 @@ static int esme_link_read_cb(struct osmo_fd *ofd) esme->read_idx += rc; if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); - if (esme->read_len <= 4) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read length too small %d\n", + if (esme->read_len <= 4 || esme->read_len > SSIZE_MAX) { + LOGP(DSMPP, LOGL_ERROR, "[%s] length invalid %d\n", esme->system_id, esme->read_len); goto dead_socket; } @@ -811,7 +811,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", esme->system_id, rc, strerror(errno)); goto dead_socket; } else if (rc == 0) { -- 1.8.4.2 From holger at freyther.de Fri Jan 17 17:23:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 17 Jan 2014 18:23:38 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> Message-ID: <20140117172338.GC10578@xiaoyu.lan> On Fri, Jan 17, 2014 at 05:26:26PM +0100, Daniel Willmann wrote: > - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", > - esme->system_id, rc); > + /* EINTR is a non-fatal error, just try again */ > + if (errno == EINTR) > + return 0; > if (rc < 0) { > - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", > - esme->system_id, rc); > + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", > + esme->system_id, rc, strerror(errno)); > + goto dead_socket; For reference. you should make the errno check in both cases or just simplify the reading part and move the error handling to a macro. From dwillmann at sysmocom.de Mon Jan 20 18:47:23 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Mon, 20 Jan 2014 19:47:23 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <20140117172338.GC10578@xiaoyu.lan> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> <20140117172338.GC10578@xiaoyu.lan> Message-ID: <20140120184723.GA21940@adrastea.totalueberwachung.de> On Fri, 2014-01-17 at 18:23, Holger Hans Peter Freyther wrote: > On Fri, Jan 17, 2014 at 05:26:26PM +0100, Daniel Willmann wrote: > > For reference. you should make the errno check in both cases or just > simplify the reading part and move the error handling to a macro. Good catch, thanks. I made the checks into a macro which should eventually end up in libosmocore so it's usable by other projects as well. I found another issue as well which I rolled into my last patch. msgb_alloc takes a uint16_t as size so the check was still wrong. I rebased and pushed the new patches to daniel/smpp-fixes 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 holger at freyther.de Mon Jan 20 19:28:07 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 20 Jan 2014 20:28:07 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <20140120184723.GA21940@adrastea.totalueberwachung.de> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> <20140117172338.GC10578@xiaoyu.lan> <20140120184723.GA21940@adrastea.totalueberwachung.de> Message-ID: <20140120192807.GT27930@xiaoyu.lan> On Mon, Jan 20, 2014 at 07:47:23PM +0100, Daniel Willmann wrote: > I found another issue as well which I rolled into my last patch. > msgb_alloc takes a uint16_t as size so the check was still wrong. good catch! Shall we export something from MSGB to indicate the maximum msgb size? From dwillmann at sysmocom.de Tue Jan 21 13:32:57 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Tue, 21 Jan 2014 14:32:57 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <20140120192807.GT27930@xiaoyu.lan> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> <20140117172338.GC10578@xiaoyu.lan> <20140120184723.GA21940@adrastea.totalueberwachung.de> <20140120192807.GT27930@xiaoyu.lan> Message-ID: <20140121133257.GE21940@adrastea.totalueberwachung.de> On Mon, 2014-01-20 at 20:28, Holger Hans Peter Freyther wrote: > On Mon, Jan 20, 2014 at 07:47:23PM +0100, Daniel Willmann wrote: > > > I found another issue as well which I rolled into my last patch. > > msgb_alloc takes a uint16_t as size so the check was still wrong. > > good catch! Shall we export something from MSGB to indicate the > maximum msgb size? I'm not opposed, but I don't see how it would help anything. I doubt that whoever forgot to check the function signature will remember to compare the length against a define. 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 holger at freyther.de Sun Jan 26 07:44:53 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 08:44:53 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <20140121133257.GE21940@adrastea.totalueberwachung.de> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> <20140117172338.GC10578@xiaoyu.lan> <20140120184723.GA21940@adrastea.totalueberwachung.de> <20140120192807.GT27930@xiaoyu.lan> <20140121133257.GE21940@adrastea.totalueberwachung.de> Message-ID: <20140126074453.GM9524@xiaoyu.lan> On Tue, Jan 21, 2014 at 02:32:57PM +0100, Daniel Willmann wrote: > I'm not opposed, but I don't see how it would help anything. I doubt > that whoever forgot to check the function signature will remember to > compare the length against a define. Maybe it is time for gerrit or at least a set-up for patchwork. I had a look at your branch and stopped at the first commit message. :) "Before this patch we just loop over the fd with read returning -1.." ==> looped (past tense)? "EINTR is handled to not cause an error and because the socket is not opened with O_NONBLOCK we don't need to check EAGAIN/EWOULDBLOCK." I don't think it is true. osmo_fd_register will enable O_NONBLOCK on the socket and I think we use that to register the fd. the actual fixes look nice though. :) From dwillmann at sysmocom.de Tue Jan 28 17:26:26 2014 From: dwillmann at sysmocom.de (Daniel Willmann) Date: Tue, 28 Jan 2014 18:26:26 +0100 Subject: [PATCH 1/3] smpp_smsc: Print errno and close socket if read returns -1 In-Reply-To: <20140126074453.GM9524@xiaoyu.lan> References: <1389975988-11277-1-git-send-email-dwillmann@sysmocom.de> <20140117172338.GC10578@xiaoyu.lan> <20140120184723.GA21940@adrastea.totalueberwachung.de> <20140120192807.GT27930@xiaoyu.lan> <20140121133257.GE21940@adrastea.totalueberwachung.de> <20140126074453.GM9524@xiaoyu.lan> Message-ID: <20140128172626.GB12355@adrastea.totalueberwachung.de> On Sun, 2014-01-26 at 08:44, Holger Hans Peter Freyther wrote: > Maybe it is time for gerrit or at least a set-up for patchwork. I had > a look at your branch and stopped at the first commit message. :) In an attempt to prevent issues with my other patches I reviewed them again and found some more issues. I pushed an updated and rebased version to daniel/smpp-fixes and will send the patchset here as well. > "Before this patch we just loop over the fd with read returning -1.." > ==> looped (past tense)? Right, fixed. > I don't think it is true. osmo_fd_register will enable O_NONBLOCK on > the socket and I think we use that to register the fd. You're right, the reason is wrong. Checking for these codes is still not needed, though (since we get called only if there's something to read. > the actual fixes look nice though. :) At least something :-) 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 daniel at sysmocom.de Tue Jan 28 17:30:39 2014 From: daniel at sysmocom.de (Daniel Willmann) Date: Tue, 28 Jan 2014 18:30:39 +0100 Subject: [PATCH 1/3] smpp_smsc: Fix socket read() error handling In-Reply-To: <20140128172626.GB12355@adrastea.totalueberwachung.de> References: <20140128172626.GB12355@adrastea.totalueberwachung.de> Message-ID: From: Daniel Willmann Read returning -1 is an error here so make sure to print the actual reason and close the socket. Before this patch we just looped over the fd with read returning -1 every time. EINTR is handled to not cause an error and we don't need to check EAGAIN/EWOULDBLOCK since the callback is only called in case there is something to read. To avoid copy&paste issues the check is implemented as a macro and the log message moved into a separate if. --- openbsc/src/libmsc/smpp_smsc.c | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index 64ed200..1e9829b 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -762,6 +762,23 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses) return rc; } +/* This macro should be called after a call to read() in the read_cb of an + * osmo_fd to properly check for errors. + * rc is the return value of read, err_label is the label to jump to in case of + * an error. The code there should handle closing the connection. + * FIXME: This code should go in libosmocore utils.h so it can be used by other + * projects as well. + * */ +#define OSMO_FD_CHECK_READ(rc, err_label) \ + if (rc < 0) { \ + /* EINTR is a non-fatal error, just try again */ \ + if (errno == EINTR) \ + return 0; \ + goto err_label; \ + } else if (rc == 0) { \ + goto err_label; \ + } + /* !\brief call-back when per-ESME TCP socket has some data to be read */ static int esme_link_read_cb(struct osmo_fd *ofd) { @@ -777,13 +794,13 @@ static int esme_link_read_cb(struct osmo_fd *ofd) case READ_ST_IN_LEN: rdlen = sizeof(uint32_t) - esme->read_idx; rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); - } else if (rc == 0) { - goto dead_socket; - } else - esme->read_idx += rc; + if (rc < 0) + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + esme->system_id, rc, strerror(errno)); + OSMO_FD_CHECK_READ(rc, dead_socket); + + esme->read_idx += rc; + if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); msg = msgb_alloc(esme->read_len, "SMPP Rx"); @@ -800,15 +817,13 @@ static int esme_link_read_cb(struct osmo_fd *ofd) msg = esme->read_msg; rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); - } else if (rc == 0) { - goto dead_socket; - } else { - esme->read_idx += rc; - msgb_put(msg, rc); - } + if (rc < 0) + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + esme->system_id, rc, strerror(errno)); + OSMO_FD_CHECK_READ(rc, dead_socket); + + esme->read_idx += rc; + msgb_put(msg, rc); if (esme->read_idx >= esme->read_len) { rc = smpp_pdu_rx(esme, esme->read_msg); -- 1.8.4.2 From daniel at sysmocom.de Tue Jan 28 17:30:40 2014 From: daniel at sysmocom.de (Daniel Willmann) Date: Tue, 28 Jan 2014 18:30:40 +0100 Subject: [PATCH 2/3] smpp_smsc: Check that the size is large enough to hold actual data In-Reply-To: References: <20140128172626.GB12355@adrastea.totalueberwachung.de> Message-ID: From: Daniel Willmann The first 4 bytes are the length including the length field. For length < 4 the subsequent msgb_put(msg, sizeof(uint32_t)) will fail, resulting in an abort. The code also expects (in smpp_msgb_cmdid()) the existence of 4 more bytes for the SMPP command ID. This patch checks that the length received is large enough to hold all 8 bytes in the msgb and drops the connection if that's not the case. The issue is reproducible with: echo -e "\x00\x00\x00\x02\x00" |socat stdin tcp:localhost:2775 --- openbsc/src/libmsc/smpp_smsc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index 1e9829b..605bdd5 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -803,6 +803,12 @@ static int esme_link_read_cb(struct osmo_fd *ofd) if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); + if (esme->read_len < 8) { + LOGP(DSMPP, LOGL_ERROR, "[%s] read length too small %u\n", + esme->system_id, esme->read_len); + goto dead_socket; + } + msg = msgb_alloc(esme->read_len, "SMPP Rx"); if (!msg) return -ENOMEM; -- 1.8.4.2 From daniel at sysmocom.de Tue Jan 28 17:30:41 2014 From: daniel at sysmocom.de (Daniel Willmann) Date: Tue, 28 Jan 2014 18:30:41 +0100 Subject: [PATCH 3/3] smpp_smsc: Fix integer overflow in read return value and msgb_alloc() In-Reply-To: References: <20140128172626.GB12355@adrastea.totalueberwachung.de> Message-ID: <3386e4447df52c62fa08374a2e795f00f08b3a1b.1390930241.git.daniel@totalueberwachung.de> From: Daniel Willmann The size parameter of msgb_alloc is uint16_t so any length value above 65535 will allocate a msgb with incorrect size. This patch changes the type of rdlen and rc to ssize_t (the return value of read) and guards against the read length being larger than UINT16_MAX. To reproduce the issue run: echo -en "\x00\x01\x00\x01\x01" |socat stdin tcp:localhost:2775 --- openbsc/src/libmsc/smpp_smsc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index 605bdd5..048c1b8 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -787,15 +788,14 @@ static int esme_link_read_cb(struct osmo_fd *ofd) uint8_t *lenptr = (uint8_t *) &len; uint8_t *cur; struct msgb *msg; - int rdlen; - int rc; + ssize_t rdlen, rc; switch (esme->read_state) { case READ_ST_IN_LEN: rdlen = sizeof(uint32_t) - esme->read_idx; rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", esme->system_id, rc, strerror(errno)); OSMO_FD_CHECK_READ(rc, dead_socket); @@ -803,8 +803,8 @@ static int esme_link_read_cb(struct osmo_fd *ofd) if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); - if (esme->read_len < 8) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read length too small %u\n", + if (esme->read_len < 8 || esme->read_len > UINT16_MAX) { + LOGP(DSMPP, LOGL_ERROR, "[%s] length invalid %u\n", esme->system_id, esme->read_len); goto dead_socket; } @@ -824,7 +824,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d (%s)\n", + LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", esme->system_id, rc, strerror(errno)); OSMO_FD_CHECK_READ(rc, dead_socket); -- 1.8.4.2 From alvaroneay at gmail.com Sat Jan 18 11:07:18 2014 From: alvaroneay at gmail.com (Alvaro Neira) Date: Sat, 18 Jan 2014 12:07:18 +0100 Subject: [PATCH] doc/examples: osmo-nitb: Fix no voice when using sysmobts Message-ID: <20140118110718.14355.1531.stgit@Ph0enix> From: ?lvaro Neira Ayuso If the default codec is not specified, I get no voice in my calls. This patch adds the parameters default-codec tch-f and tch-h to get the voice working. Signed-off-by: Alvaro Neira Ayuso --- openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg index 7a44308..0eda9f6 100644 --- a/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg +++ b/openbsc/doc/examples/osmo-nitb/nanobts/openbsc.cfg @@ -75,3 +75,6 @@ network phys_chan_config TCH/F timeslot 7 phys_chan_config TCH/F +mncc-int + default-codec tch-f amr + default-codec tch-h amr From holger at freyther.de Sun Jan 19 15:59:47 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 19 Jan 2014 16:59:47 +0100 Subject: [PATCH] doc/examples: osmo-nitb: Fix no voice when using sysmobts In-Reply-To: <20140118110718.14355.1531.stgit@Ph0enix> References: <20140118110718.14355.1531.stgit@Ph0enix> Message-ID: <20140119155947.GA24191@xiaoyu.lan> On Sat, Jan 18, 2014 at 12:07:18PM +0100, Alvaro Neira wrote: Dear Alvaro, > If the default codec is not specified, I get no voice in my calls. > This patch adds the parameters default-codec tch-f and tch-h to get > the voice working. can you provide a bit more context? Which IP based BTS do you use? What codec has been selected by default? is that with the latest OpenBSC (~3-4 days ago the default codec has been changed to FR1). kind regards holger From jolly at eversberg.eu Wed Jan 22 09:05:50 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:50 +0100 Subject: [PATCH 1/9] Add function to update TRAU muxer after assignment or handover Message-ID: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> From: Andreas Eversberg E1 based BTS use TRAU muxer to decode TRAU frames. After changing channel from one timeslot to another (due to handover or assignment), the TRAU muxer must be updated. The call reference of the call is disconnected from the old channel and connected to the new channel. --- openbsc/include/openbsc/gsm_data.h | 14 ++++++++++++++ openbsc/include/openbsc/trau_mux.h | 3 +++ openbsc/src/libbsc/bsc_api.c | 5 +++++ openbsc/src/libbsc/handover_logic.c | 7 +++++-- openbsc/src/libmsc/gsm_04_08.c | 12 +++++++++--- openbsc/src/libtrau/trau_mux.c | 18 ++++++++++++++++++ 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 7c3ca84..41fe328 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -382,6 +382,20 @@ static inline int is_nokia_bts(struct gsm_bts *bts) return 0; } +static inline int is_e1_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_BS11: + case GSM_BTS_TYPE_RBS2000: + case GSM_BTS_TYPE_NOKIA_SITE: + return 1; + default: + break; + } + + return 0; +} + enum gsm_auth_policy gsm_auth_policy_parse(const char *arg); const char *gsm_auth_policy_name(enum gsm_auth_policy policy); diff --git a/openbsc/include/openbsc/trau_mux.h b/openbsc/include/openbsc/trau_mux.h index 3de50f7..d211d8d 100644 --- a/openbsc/include/openbsc/trau_mux.h +++ b/openbsc/include/openbsc/trau_mux.h @@ -51,6 +51,9 @@ int trau_recv_lchan(struct gsm_lchan *lchan, uint32_t callref); /* send trau from application */ int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame); +/* switch trau muxer to new lchan */ +int switch_trau_mux(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan); + /* callback invoked if we receive TRAU frames */ int subch_cb(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *_priv); diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 86d2493..e567038 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -419,6 +420,10 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn, return; } + /* switch TRAU muxer for E1 based BTS from one channel to another */ + if (is_e1_bts(conn->bts)) + switch_trau_mux(conn->lchan, conn->secondary_lchan); + /* swap channels */ osmo_timer_del(&conn->T10); diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c index 9cf26af..36a758b 100644 --- a/openbsc/src/libbsc/handover_logic.c +++ b/openbsc/src/libbsc/handover_logic.c @@ -39,6 +39,7 @@ #include #include #include +#include struct bsc_handover { struct llist_head list; @@ -264,6 +265,10 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan) osmo_timer_del(&ho->T3103); + /* switch TRAU muxer for E1 based BTS from one channel to another */ + if (is_e1_bts(new_lchan->conn->bts)) + switch_trau_mux(ho->old_lchan, new_lchan); + /* Replace the ho lchan with the primary one */ if (ho->old_lchan != new_lchan->conn->lchan) LOGP(DHO, LOGL_ERROR, "Primary lchan changed during handover.\n"); @@ -278,8 +283,6 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan) rsl_lchan_set_state(ho->old_lchan, LCHAN_S_INACTIVE); lchan_release(ho->old_lchan, 0, RSL_REL_LOCAL_END); - /* do something to re-route the actual speech frames ! */ - llist_del(&ho->list); talloc_free(ho); diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 0c6b100..dbb30ec 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1648,6 +1648,9 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) lchan = trans->conn->lchan; bts = lchan->ts->trx->bts; + /* store receive state */ + trans->tch_recv = enable; + switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: case GSM_BTS_TYPE_OSMO_SYSMO: @@ -1655,10 +1658,8 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; } - /* in case, we don't have a RTP socket yet, we note this - * in the transaction and try later */ + /* in case, we don't have a RTP socket yet, we try later */ if (!lchan->abis_ip.rtp_socket) { - trans->tch_recv = enable; DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable); return 0; } @@ -1677,6 +1678,11 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) case GSM_BTS_TYPE_BS11: case GSM_BTS_TYPE_RBS2000: case GSM_BTS_TYPE_NOKIA_SITE: + /* in case we don't have a TCH with correct mode, we try later */ + if (lchan->tch_mode == GSM48_CMODE_SIGN) { + DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable); + return 0; + } if (enable) return trau_recv_lchan(lchan, callref); return trau_mux_unmap(NULL, callref); diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index c9d77cf..7b9bac0 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -31,6 +31,7 @@ #include #include #include +#include /* this corresponds to the bit-lengths of the individual codec * parameters as indicated in Table 1.1 of TS 06.10 */ @@ -518,3 +519,20 @@ int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame) return subchan_mux_enqueue(mx, dst_e1_ss->e1_ts_ss, trau_bits_out, TRAU_FRAME_BITS); } + +/* switch trau muxer to new lchan */ +int switch_trau_mux(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan) +{ + struct gsm_network *net = old_lchan->ts->trx->bts->network; + struct gsm_trans *trans; + + /* look up transaction with TCH frame receive enabled */ + llist_for_each_entry(trans, &net->trans_list, entry) { + if (trans->conn && trans->conn->lchan == old_lchan && trans->tch_recv) { + /* switch */ + trau_recv_lchan(new_lchan, trans->callref); + } + } + + return 0; +} -- 1.8.1.5 From jolly at eversberg.eu Wed Jan 22 09:05:51 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:51 +0100 Subject: [PATCH 2/9] Use 'defines' for length and duration of RTP payload In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-2-git-send-email-jolly@eversberg.eu> --- openbsc/include/openbsc/rtp_proxy.h | 4 ++++ openbsc/src/libtrau/rtp_proxy.c | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index 26cac0d..52ffefd 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -33,6 +33,10 @@ #define RTP_PT_GSM_HALF 96 #define RTP_PT_GSM_EFR 97 #define RTP_PT_AMR 98 +#define RTP_LEN_GSM_FULL 33 +#define RTP_LEN_GSM_HALF 15 +#define RTP_LEN_GSM_EFR 31 +#define RTP_GSM_DURATION 160 enum rtp_rx_action { RTP_NONE, diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 4278fc6..94a5b2f 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -167,15 +167,21 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) switch (rtph->payload_type) { case RTP_PT_GSM_FULL: msg_type = GSM_TCHF_FRAME; - if (payload_len != 33) { + if (payload_len != RTP_LEN_GSM_FULL) { DEBUGPC(DLMUX, "received RTP full rate frame with " - "payload length != 32 (len = %d)\n", - payload_len); + "payload length != %d (len = %d)\n", + RTP_LEN_GSM_FULL, payload_len); return -EINVAL; } break; case RTP_PT_GSM_EFR: msg_type = GSM_TCHF_FRAME_EFR; + if (payload_len != RTP_LEN_GSM_EFR) { + DEBUGPC(DLMUX, "received RTP extended full rate frame " + "with payload length != %d (len = %d)\n", + RTP_LEN_GSM_EFR, payload_len); + return -EINVAL; + } break; default: DEBUGPC(DLMUX, "received RTP frame with unknown payload " @@ -236,13 +242,13 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) switch (frame->msg_type) { case GSM_TCHF_FRAME: payload_type = RTP_PT_GSM_FULL; - payload_len = 33; - duration = 160; + payload_len = RTP_LEN_GSM_FULL; + duration = RTP_GSM_DURATION; break; case GSM_TCHF_FRAME_EFR: payload_type = RTP_PT_GSM_EFR; - payload_len = 31; - duration = 160; + payload_len = RTP_LEN_GSM_EFR; + duration = RTP_GSM_DURATION; break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", -- 1.8.1.5 From holger at freyther.de Sun Jan 26 07:50:36 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 08:50:36 +0100 Subject: [PATCH 2/9] Use 'defines' for length and duration of RTP payload In-Reply-To: <1390381558-20914-2-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-2-git-send-email-jolly@eversberg.eu> Message-ID: <20140126075036.GO9524@xiaoyu.lan> On Wed, Jan 22, 2014 at 10:05:51AM +0100, Andreas Eversberg wrote: > + if (payload_len != RTP_LEN_GSM_EFR) { > + DEBUGPC(DLMUX, "received RTP extended full rate frame " > + "with payload length != %d (len = %d)\n", > + RTP_LEN_GSM_EFR, payload_len); > + return -EINVAL; > + } this is not mentioned in the commit message. I am applying it anyway. From jolly at eversberg.eu Wed Jan 22 09:05:52 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:52 +0100 Subject: [PATCH 3/9] Add support for half rate V1 frames to MNCC/RTP interface In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-3-git-send-email-jolly@eversberg.eu> --- openbsc/include/openbsc/mncc.h | 1 + openbsc/src/libmsc/gsm_04_08.c | 6 ++++-- openbsc/src/libmsc/mncc_builtin.c | 2 ++ openbsc/src/libmsc/mncc_sock.c | 5 +++-- openbsc/src/libtrau/rtp_proxy.c | 14 ++++++++++++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index ffc247b..ec4dac9 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -95,6 +95,7 @@ struct gsm_call { #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 +#define GSM_TCHH_FRAME 0x0302 #define GSM_TCHF_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index dbb30ec..46ad719 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -2945,6 +2945,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) return tch_recv_mncc(net, data->callref, 1); case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: + case GSM_TCHH_FRAME: /* Find callref */ trans = trans_find_by_callref(net, data->callref); if (!trans) { @@ -2956,11 +2957,12 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); return 0; } - if (trans->conn->lchan->type != GSM_LCHAN_TCH_F) { + if (trans->conn->lchan->type != GSM_LCHAN_TCH_F + && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { /* This should be LOGL_ERROR or NOTICE, but * unfortuantely it happens for a couple of frames at * the beginning of every RTP connection */ - LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F\n"); + LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); return 0; } bts = trans->conn->lchan->ts->trx->bts; diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c index be35454..506d004 100644 --- a/openbsc/src/libmsc/mncc_builtin.c +++ b/openbsc/src/libmsc/mncc_builtin.c @@ -342,6 +342,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) switch (msg_type) { case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: + case GSM_TCHH_FRAME: break; default: DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, @@ -410,6 +411,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) break; case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: + case GSM_TCHH_FRAME: rc = mncc_rcv_tchf(call, msg_type, arg); break; default: diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index cf4bca8..8d8e505 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -54,8 +54,9 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) if (net->mncc_state->conn_bfd.fd < 0) { LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app " "but socket is gone\n", get_mncc_name(msg_type)); - if (msg_type != GSM_TCHF_FRAME && - msg_type != GSM_TCHF_FRAME_EFR) { + if (msg_type != GSM_TCHF_FRAME + && msg_type != GSM_TCHF_FRAME_EFR + && msg_type != GSM_TCHH_FRAME) { /* release the request */ struct gsm_mncc mncc_out; memset(&mncc_out, 0, sizeof(mncc_out)); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 94a5b2f..2587e12 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -183,6 +183,15 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; + case RTP_PT_GSM_HALF: + msg_type = GSM_TCHH_FRAME; + if (payload_len != RTP_LEN_GSM_HALF) { + DEBUGPC(DLMUX, "received RTP half rate frame with " + "payload length != 15 (len = %d)\n", + RTP_LEN_GSM_HALF, payload_len); + return -EINVAL; + } + break; default: DEBUGPC(DLMUX, "received RTP frame with unknown payload " "type %d\n", rtph->payload_type); @@ -250,6 +259,11 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) payload_len = RTP_LEN_GSM_EFR; duration = RTP_GSM_DURATION; break; + case GSM_TCHH_FRAME: + payload_type = RTP_PT_GSM_HALF; + payload_len = RTP_LEN_GSM_HALF; + duration = RTP_GSM_DURATION; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); -- 1.8.1.5 From jolly at eversberg.eu Wed Jan 22 09:05:53 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:53 +0100 Subject: [PATCH 4/9] Add support for AMR frames to MNCC/RTP interface In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-4-git-send-email-jolly@eversberg.eu> AMR rate is currently fixed to 5.9k. --- openbsc/include/openbsc/mncc.h | 1 + openbsc/src/libmsc/gsm_04_08.c | 1 + openbsc/src/libmsc/mncc.c | 5 ++++- openbsc/src/libmsc/mncc_builtin.c | 2 ++ openbsc/src/libmsc/mncc_sock.c | 3 ++- openbsc/src/libtrau/rtp_proxy.c | 21 +++++++++++++++++---- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index ec4dac9..45ad83e 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -96,6 +96,7 @@ struct gsm_call { #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 #define GSM_TCHH_FRAME 0x0302 +#define GSM_TCH_FRAME_AMR 0x0303 #define GSM_TCHF_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 46ad719..e36a142 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -2946,6 +2946,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: + case GSM_TCH_FRAME_AMR: /* Find callref */ trans = trans_find_by_callref(net, data->callref); if (!trans) { diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c index b484772..01e9c67 100644 --- a/openbsc/src/libmsc/mncc.c +++ b/openbsc/src/libmsc/mncc.c @@ -84,7 +84,10 @@ static struct mncc_names { {"MNCC_FRAME_DROP", 0x0202}, {"MNCC_LCHAN_MODIFY", 0x0203}, - {"GSM_TCH_FRAME", 0x0300}, + {"GSM_TCHF_FRAME", 0x0300}, + {"GSM_TCHF_FRAME_EFR", 0x0301}, + {"GSM_TCHH_FRAME", 0x0302}, + {"GSM_TCH_FRAME_AMR", 0x0303}, {NULL, 0} }; diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c index 506d004..5d71983 100644 --- a/openbsc/src/libmsc/mncc_builtin.c +++ b/openbsc/src/libmsc/mncc_builtin.c @@ -343,6 +343,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: + case GSM_TCH_FRAME_AMR: break; default: DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, @@ -412,6 +413,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: + case GSM_TCH_FRAME_AMR: rc = mncc_rcv_tchf(call, msg_type, arg); break; default: diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index 8d8e505..4a880c7 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -56,7 +56,8 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) "but socket is gone\n", get_mncc_name(msg_type)); if (msg_type != GSM_TCHF_FRAME && msg_type != GSM_TCHF_FRAME_EFR - && msg_type != GSM_TCHH_FRAME) { + && msg_type != GSM_TCHH_FRAME + && msg_type != GSM_TCH_FRAME_AMR) { /* release the request */ struct gsm_mncc mncc_out; memset(&mncc_out, 0, sizeof(mncc_out)); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 2587e12..59efa21 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -116,6 +116,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) int payload_len; int msg_type; int x_len; + int amr = 0; if (msg->len < 12) { DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n", @@ -192,21 +193,26 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; + case RTP_PT_AMR: + amr = 1; + break; default: DEBUGPC(DLMUX, "received RTP frame with unknown payload " "type %d\n", rtph->payload_type); return -EINVAL; } - new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len, + new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len + amr, "GSM-DATA"); if (!new_msg) return -ENOMEM; frame = (struct gsm_data_frame *)(new_msg->data); frame->msg_type = msg_type; frame->callref = callref; - memcpy(frame->data, payload, payload_len); - msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len); + if (amr) + frame->data[0] = payload_len; + memcpy(frame->data + amr, payload, payload_len); + msgb_put(new_msg, sizeof(struct gsm_data_frame) + amr + payload_len); *data = new_msg; return 0; @@ -239,6 +245,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int payload_type; int payload_len; int duration; /* in samples */ + int amr = 0; if (rs->tx_action != RTP_SEND_DOWNSTREAM) { /* initialize sequences */ @@ -264,6 +271,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) payload_len = RTP_LEN_GSM_HALF; duration = RTP_GSM_DURATION; break; + case GSM_TCH_FRAME_AMR: + payload_type = RTP_PT_AMR; + payload_len = frame->data[0]; + duration = RTP_GSM_DURATION; + amr = 1; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); @@ -305,7 +318,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) rtph->timestamp = htonl(rs->transmit.timestamp); rs->transmit.timestamp += duration; rtph->ssrc = htonl(rs->transmit.ssrc); - memcpy(msg->data + sizeof(struct rtp_hdr), frame->data, payload_len); + memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + amr, payload_len); msgb_put(msg, sizeof(struct rtp_hdr) + payload_len); msgb_enqueue(&rss->tx_queue, msg); rss->bfd.when |= BSC_FD_WRITE; -- 1.8.1.5 From jolly at eversberg.eu Wed Jan 22 09:05:54 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:54 +0100 Subject: [PATCH 5/9] Adding handling of BFI (Bad Frame Indicatior) of received TRAU frames In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-5-git-send-email-jolly@eversberg.eu> If a bad TRAU frame is received, it is forwarded to MNCC application as GSM_BAD_FRAME. The application can now handle the GAP of missing audio. (e.g. by extrapolation) If TRAU frames are forwarded via RTP, bad frames are dropped, but frame counter and timestamp of RTP sender state is increased. --- openbsc/include/openbsc/mncc.h | 2 +- openbsc/src/libmsc/mncc_sock.c | 3 ++- openbsc/src/libtrau/rtp_proxy.c | 11 +++++++++++ openbsc/src/libtrau/trau_mux.c | 7 +++++-- openbsc/tests/trau/trau_test.c | 2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index 45ad83e..48f4f7d 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -97,7 +97,7 @@ struct gsm_call { #define GSM_TCHF_FRAME_EFR 0x0301 #define GSM_TCHH_FRAME 0x0302 #define GSM_TCH_FRAME_AMR 0x0303 -#define GSM_TCHF_BAD_FRAME 0x03ff +#define GSM_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index 4a880c7..c8cfa6a 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -57,7 +57,8 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) if (msg_type != GSM_TCHF_FRAME && msg_type != GSM_TCHF_FRAME_EFR && msg_type != GSM_TCHH_FRAME - && msg_type != GSM_TCH_FRAME_AMR) { + && msg_type != GSM_TCH_FRAME_AMR + && msg_type != GSM_BAD_FRAME) { /* release the request */ struct gsm_mncc mncc_out; memset(&mncc_out, 0, sizeof(mncc_out)); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 59efa21..89ed8a4 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -277,6 +277,14 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) duration = RTP_GSM_DURATION; amr = 1; break; + case GSM_BAD_FRAME: + /* in case of a bad frame, just count and drop packt */ + payload_type = 0; + payload_len = 0; + duration = RTP_GSM_DURATION; + rs->transmit.timestamp += duration; + rs->transmit.sequence++; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); @@ -304,6 +312,9 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) } } + if (frame->msg_type == GSM_BAD_FRAME) + return 0; + msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL"); if (!msg) return -ENOMEM; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index 7b9bac0..bb513cc 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -242,7 +242,10 @@ struct msgb *trau_decode_fr(uint32_t callref, i++; j++; } - frame->msg_type = GSM_TCHF_FRAME; + if (tf->c_bits[11]) /* BFI */ + frame->msg_type = GSM_BAD_FRAME; + else + frame->msg_type = GSM_TCHF_FRAME; frame->callref = callref; msgb_put(msg, sizeof(struct gsm_data_frame) + 33); @@ -314,7 +317,7 @@ struct msgb *trau_decode_efr(uint32_t callref, return msg; bad_frame: - frame->msg_type = GSM_TCHF_BAD_FRAME; + frame->msg_type = GSM_BAD_FRAME; return msg; } diff --git a/openbsc/tests/trau/trau_test.c b/openbsc/tests/trau/trau_test.c index f8a48db..b95f1e8 100644 --- a/openbsc/tests/trau/trau_test.c +++ b/openbsc/tests/trau/trau_test.c @@ -57,7 +57,7 @@ void test_trau_fr_efr(unsigned char *data) msg = trau_decode_efr(1, &tf); OSMO_ASSERT(msg != NULL); frame = (struct gsm_data_frame *)msg->data; - OSMO_ASSERT(frame->msg_type == GSM_TCHF_BAD_FRAME); + OSMO_ASSERT(frame->msg_type == GSM_BAD_FRAME); msgb_free(msg); } -- 1.8.1.5 From jolly at eversberg.eu Wed Jan 22 09:05:55 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:55 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-6-git-send-email-jolly@eversberg.eu> Instead of forwarding traffic through MNCC interface, traffic can be forwarded to a given RTP peer directly. A special MNCC message is used to control the peer's destination. The traffic can still be forwarded through MNCC interface when this special MNCC message is not used. It also works with E1 based BTSs. In conjunction with LCR's "rtp-bridge" feature, the RTP traffic can be directly exchanged with a remote SIP endpoint, so that the traffic is not forwarded by LCR itself. This way the performance of handling traffic only depends on OpenBSC and the remote SIP endpoint. Also the traffic is exchanged with the SIP endpoint without transcoding, to have maximum performance. --- openbsc/include/openbsc/gsm_04_08.h | 3 + openbsc/include/openbsc/mncc.h | 10 ++ openbsc/include/openbsc/rtp_proxy.h | 5 +- openbsc/include/openbsc/transaction.h | 2 + openbsc/src/ipaccess/ipaccess-config.c | 6 ++ openbsc/src/libbsc/bsc_api.c | 1 + openbsc/src/libbsc/handover_logic.c | 1 + openbsc/src/libmsc/gsm_04_08.c | 176 ++++++++++++++++++++++++++------- openbsc/src/libmsc/mncc_sock.c | 18 ++++ openbsc/src/libmsc/transaction.c | 1 + openbsc/src/libtrau/rtp_proxy.c | 20 +++- openbsc/src/libtrau/trau_mux.c | 14 ++- openbsc/src/utils/bs11_config.c | 6 ++ openbsc/tests/abis/abis_test.c | 6 ++ openbsc/tests/gbproxy/gbproxy_test.c | 6 ++ 15 files changed, 233 insertions(+), 42 deletions(-) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 8df7b73..93348d1 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -6,6 +6,7 @@ #include #include +#include struct msgb; struct gsm_bts; @@ -75,4 +76,6 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, void release_security_operation(struct gsm_subscriber_connection *conn); void allocate_security_operation(struct gsm_subscriber_connection *conn); +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data); + #endif diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index 48f4f7d..a380b8f 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -92,6 +92,9 @@ struct gsm_call { #define MNCC_FRAME_RECV 0x0201 #define MNCC_FRAME_DROP 0x0202 #define MNCC_LCHAN_MODIFY 0x0203 +#define MNCC_RTP_CREATE 0x0204 +#define MNCC_RTP_CONNECT 0x0205 +#define MNCC_RTP_FREE 0x0206 #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 @@ -179,6 +182,13 @@ struct gsm_mncc_hello { uint32_t lchan_type_offset; }; +struct gsm_mncc_rtp { + uint32_t msg_type; + uint32_t callref; + uint32_t ip; + uint16_t port; +}; + char *get_mncc_name(int value); void mncc_set_cause(struct gsm_mncc *data, int loc, int val); void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg); diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index 52ffefd..2729f63 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -40,8 +40,9 @@ enum rtp_rx_action { RTP_NONE, - RTP_PROXY, - RTP_RECV_UPSTREAM, + RTP_PROXY, /* forward from BTS to BTS */ + RTP_RECV_UPSTREAM, /* forward to L4 application */ + RTP_RECV_L4, /* receive RTP frames from L4 application */ }; enum rtp_tx_action { diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index b6c859c..6f4258d 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -28,6 +28,7 @@ struct gsm_trans { /* reference from MNCC or other application */ uint32_t callref; + uint32_t callref_keep; /* to remember callref, even if it is removed */ /* if traffic channel receive was requested */ int tch_recv; @@ -46,6 +47,7 @@ struct gsm_trans { int T308_second; /* used to send release again */ struct osmo_timer_list timer; struct gsm_mncc msg; /* stores setup/disconnect/release message */ + struct rtp_socket *rs; /* L4 traffic via RTP */ } cc; struct { struct gsm411_smc_inst smc_inst; diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index c42c7bb..68b9131 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -87,6 +87,12 @@ static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, static uint8_t unit_id_attr[] = { 0x91, 0x00, 9, '2', '3', '4', '2', '/' , '0', '/', '0', 0x00 }; */ +/* 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; +} + extern int ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what); extern struct e1inp_line_ops ipaccess_e1inp_line_ops; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index e567038..e6629ff 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c index 36a758b..e20d8f7 100644 --- a/openbsc/src/libbsc/handover_logic.c +++ b/openbsc/src/libbsc/handover_logic.c @@ -39,6 +39,7 @@ #include #include #include +#include #include struct bsc_handover { diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index e36a142..7bb9c87 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1359,8 +1359,15 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) } if (trans->cc.state != GSM_CSTATE_NULL) new_cc_state(trans, GSM_CSTATE_NULL); + /* Be sure to unmap upstream traffic for our callref only. */ if (trans->conn) - trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref); + trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref_keep); + + /* free L4 RTP socket */ + if (trans->cc.rs) { + rtp_socket_free(trans->cc.rs); + trans->cc.rs = NULL; + } } static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); @@ -1478,6 +1485,7 @@ static int switch_for_handover(struct gsm_lchan *old_lchan, new_rs->receive = old_rs->receive; break; case RTP_NONE: + case RTP_RECV_L4: break; } @@ -1695,6 +1703,130 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) return 0; } +/* handle RTP requests of L4 */ +static int mncc_rtp(struct gsm_network *net, uint32_t callref, struct gsm_mncc_rtp *mncc) +{ + struct rtp_socket *rs; + struct gsm_trans *trans; + int rc; + + /* Find callref */ + trans = trans_find_by_callref(net, callref); + if (!trans) { + LOGP(DCC, LOGL_ERROR, "Unknown transaction for callref=%d\n", callref); + return -EINVAL; + } + + rs = trans->cc.rs; + + switch (mncc->msg_type) { + case MNCC_RTP_CREATE: + /* use RTP instead of MNCC socket, for traffic + * open L4 RTP socket */ + if (rs) { + LOGP(DCC, LOGL_ERROR, "RTP already created.\n"); + return -EIO; + } + rs = trans->cc.rs = rtp_socket_create(); + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP socket creation failed.\n"); + /* reply with IP/port = 0 */ + mncc->ip = 0; + mncc->port = 0; + mncc_recvmsg(net, trans, MNCC_RTP_CREATE, (struct gsm_mncc *)mncc); + return -EIO; + } + rs->rx_action = RTP_RECV_L4; + rs->receive.net = net; + rs->receive.callref = callref; + /* reply with bound IP/port */ + mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); + mncc->port = ntohs(rs->rtp.sin_local.sin_port); + mncc_recvmsg(net, trans, MNCC_RTP_CREATE, (struct gsm_mncc *)mncc); + break; + case MNCC_RTP_CONNECT: + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP not created.\n"); + return -EIO; + } + rc = rtp_socket_connect(trans->cc.rs, mncc->ip, mncc->port); + if (rc < 0) { + LOGP(DCC, LOGL_ERROR, "RTP socket connect failed.\n"); + /* reply with IP/port = 0 */ + mncc->ip = 0; + mncc->port = 0; + mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, (struct gsm_mncc *)mncc); + return -EIO; + } + /* reply with local IP/port */ + mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); + mncc->port = ntohs(rs->rtp.sin_local.sin_port); + mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, (struct gsm_mncc *)mncc); + break; + case MNCC_RTP_FREE: + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP not created.\n"); + return -EIO; + } + rtp_socket_free(trans->cc.rs); + trans->cc.rs = NULL; + /* reply */ + mncc_recvmsg(net, trans, MNCC_RTP_FREE, (struct gsm_mncc *)mncc); + break; + } + + return 0; +} + +/* handle tch frame from L4 */ +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) +{ + struct gsm_trans *trans; + struct gsm_bts *bts; + + /* Find callref */ + trans = trans_find_by_callref(net, data->callref); + if (!trans) { + LOGP(DMNCC, LOGL_ERROR, "TCH frame for non-existing trans\n"); + return -EIO; + } + if (!trans->conn) { + LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); + return 0; + } + if (trans->conn->lchan->type != GSM_LCHAN_TCH_F + && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { + /* This should be LOGL_ERROR or NOTICE, but + * unfortuantely it happens for a couple of frames at + * the beginning of every RTP connection */ + LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); + return 0; + } + bts = trans->conn->lchan->ts->trx->bts; + switch (bts->type) { + case GSM_BTS_TYPE_NANOBTS: + case GSM_BTS_TYPE_OSMO_SYSMO: + if (!trans->conn->lchan->abis_ip.rtp_socket) { + DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); + return 0; + } + if (trans->conn->lchan->abis_ip.rtp_socket->receive.callref != callref) { + /* Drop frame, if not our callref. This happens, if + * the call is on hold or retrieved by another + * transaction. */ + return 0; + } + return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, data); + case GSM_BTS_TYPE_BS11: + case GSM_BTS_TYPE_RBS2000: + case GSM_BTS_TYPE_NOKIA_SITE: + return trau_send_frame(trans->conn->lchan, data); + default: + LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); + } + return -EINVAL; +} + static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg) { DEBUGP(DCC, "-> STATUS ENQ\n"); @@ -2930,7 +3062,6 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) int i, rc = 0; struct gsm_trans *trans = NULL, *transt; struct gsm_subscriber_connection *conn = NULL; - struct gsm_bts *bts = NULL; struct gsm_mncc *data = arg, rel; DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type)); @@ -2943,46 +3074,15 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) return tch_recv_mncc(net, data->callref, 0); case MNCC_FRAME_RECV: return tch_recv_mncc(net, data->callref, 1); + case MNCC_RTP_CREATE: + case MNCC_RTP_CONNECT: + case MNCC_RTP_FREE: + return mncc_rtp(net, data->callref, (struct gsm_mncc_rtp *) arg); case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: case GSM_TCH_FRAME_AMR: - /* Find callref */ - trans = trans_find_by_callref(net, data->callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "TCH frame for non-existing trans\n"); - return -EIO; - } - log_set_context(BSC_CTX_SUBSCR, trans->subscr); - if (!trans->conn) { - LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); - return 0; - } - if (trans->conn->lchan->type != GSM_LCHAN_TCH_F - && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { - /* This should be LOGL_ERROR or NOTICE, but - * unfortuantely it happens for a couple of frames at - * the beginning of every RTP connection */ - LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); - return 0; - } - bts = trans->conn->lchan->ts->trx->bts; - switch (bts->type) { - case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: - if (!trans->conn->lchan->abis_ip.rtp_socket) { - DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); - return 0; - } - return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, arg); - case GSM_BTS_TYPE_BS11: - case GSM_BTS_TYPE_RBS2000: - case GSM_BTS_TYPE_NOKIA_SITE: - return trau_send_frame(trans->conn->lchan, arg); - default: - LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); - } - return -EINVAL; + return tch_frame_down(net, data->callref, (struct gsm_data_frame *) arg); } memset(&rel, 0, sizeof(struct gsm_mncc)); diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index c8cfa6a..5ae9cc4 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include struct mncc_sock_state { struct gsm_network *net; @@ -50,6 +52,22 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) struct gsm_mncc *mncc_in = (struct gsm_mncc *) msgb_data(msg); int msg_type = mncc_in->msg_type; + /* L4 uses RTP for this transaction, we send our data via RTP, + * otherwise we send it through MNCC interface */ + if (msg_type == GSM_TCHF_FRAME + || msg_type == GSM_TCHF_FRAME_EFR + || msg_type == GSM_TCHH_FRAME + || msg_type == GSM_TCH_FRAME_AMR + || msg_type == GSM_BAD_FRAME) { + struct gsm_trans *trans = trans_find_by_callref(net, mncc_in->callref); + + if (trans && trans->cc.rs) { + rtp_send_frame(trans->cc.rs, (struct gsm_data_frame *) mncc_in); + msgb_free(msg); + return 0; + } + } + /* Check if we currently have a MNCC handler connected */ if (net->mncc_state->conn_bfd.fd < 0) { LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app " diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c index e425e67..bdd3d8e 100644 --- a/openbsc/src/libmsc/transaction.c +++ b/openbsc/src/libmsc/transaction.c @@ -78,6 +78,7 @@ struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr, trans->protocol = protocol; trans->transaction_id = trans_id; trans->callref = callref; + trans->callref_keep = callref; llist_add_tail(&trans->entry, &subscr->net->trans_list); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 89ed8a4..2049911 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -470,7 +470,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) other_rss->bfd.when |= BSC_FD_WRITE; break; - case RTP_RECV_UPSTREAM: + case RTP_RECV_UPSTREAM: /* from BTS to application */ if (!rs->receive.callref || !rs->receive.net) { rc = -EIO; goto out_free; @@ -499,6 +499,24 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) trau_tx_to_mncc(rs->receive.net, new_msg); break; + case RTP_RECV_L4: /* from L4 */ + if (!rs->receive.callref || !rs->receive.net) { + rc = -EIO; + goto out_free; + } + if (rss->bfd.priv_nr != RTP_PRIV_RTP) { + rc = ENOTSUP; + goto out_free; + } + rc = rtp_decode(msg, rs->receive.callref, &new_msg); + if (rc < 0) + goto out_free; + msgb_free(msg); + tch_frame_down(rs->receive.net, rs->receive.callref, + (struct gsm_data_frame *) new_msg->data); + msgb_free(new_msg); + break; + case RTP_NONE: /* if socket exists, but disabled by app */ msgb_free(msg); break; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index bb513cc..15a84b0 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -171,7 +171,9 @@ int trau_mux_unmap(const struct gsm_e1_subslot *ss, uint32_t callref) llist_del(&ue->list); return 0; } - if (ss && !memcmp(&ue->src, ss, sizeof(*ss))) { + /* Only release, if no callref is given. We must ensure that + * only the transaction's upstream is removed, if exists. */ + if (ss && !callref && !memcmp(&ue->src, ss, sizeof(*ss))) { llist_del(&ue->list); return 0; } @@ -497,11 +499,21 @@ int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame) uint8_t trau_bits_out[TRAU_FRAME_BITS]; struct gsm_e1_subslot *dst_e1_ss = &lchan->ts->e1_link; struct subch_mux *mx; + struct upqueue_entry *ue; struct decoded_trau_frame tf; mx = e1inp_get_mux(dst_e1_ss->e1_nr, dst_e1_ss->e1_ts); if (!mx) return -EINVAL; + if (!(ue = lookup_trau_upqueue(dst_e1_ss))) { + /* Call might be on hold, so we drop frames. */ + return 0; + } + if (ue->callref != frame->callref) { + /* Slot has different transaction, due to + * another call. (Ours is on hold.) */ + return 0; + } switch (frame->msg_type) { case GSM_TCHF_FRAME: diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c index e8acb46..f459744 100644 --- a/openbsc/src/utils/bs11_config.c +++ b/openbsc/src/utils/bs11_config.c @@ -83,6 +83,12 @@ struct osmo_counter *osmo_counter_alloc(const char *name) return NULL; } +/* 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; +} + int handle_serial_msg(struct msgb *rx_msg); /* create all objects for an initial configuration */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index e7e78d2..6bb84cc 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -27,6 +27,12 @@ #include #include +/* 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; +} + static const uint8_t simple_config[] = { /*0, 13, */ 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index d32ac83..69ce58a 100644 --- 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; +} + struct gbproxy_config gbcfg; static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, -- 1.8.1.5 From holger at freyther.de Wed Jan 22 10:02:51 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 22 Jan 2014 11:02:51 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <1390381558-20914-6-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> Message-ID: <20140122100251.GB8497@xiaoyu.lan> On Wed, Jan 22, 2014 at 10:05:55AM +0100, Andreas Eversberg wrote: > openbsc/include/openbsc/mncc.h | 10 ++ We had this before. When you change the interface, increase the interface version. holger From andreas at eversberg.eu Wed Jan 22 10:10:21 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 11:10:21 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <20140122100251.GB8497@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140122100251.GB8497@xiaoyu.lan> Message-ID: <52DF990D.6010306@eversberg.eu> Holger Hans Peter Freyther wrote: >> openbsc/include/openbsc/mncc.h | 10 ++ > We had this before. When you change the interface, increase the > interface version. the patch does not break the current interface version 2. it is just an additional feature. there is already a new version 3 in my handover branch (lcr and openbsc). From holger at freyther.de Wed Jan 22 10:59:46 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 22 Jan 2014 11:59:46 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <52DF990D.6010306@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140122100251.GB8497@xiaoyu.lan> <52DF990D.6010306@eversberg.eu> Message-ID: <20140122105946.GC8497@xiaoyu.lan> On Wed, Jan 22, 2014 at 11:10:21AM +0100, Andreas Eversberg wrote: > Holger Hans Peter Freyther wrote: > >> openbsc/include/openbsc/mncc.h | 10 ++ > >We had this before. When you change the interface, increase the > >interface version. > the patch does not break the current interface version 2. it is just > an additional feature. there is already a new version 3 in my > handover branch (lcr and openbsc). how can someone using the MNCC know that the NITB supports the direct RTP mode? Unless we want to introduce feature negotiation the only way I see is to increase the version number. Or start using major and minor numbers. holger From andreas at eversberg.eu Thu Jan 23 10:59:30 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 11:59:30 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <20140122105946.GC8497@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140122100251.GB8497@xiaoyu.lan> <52DF990D.6010306@eversberg.eu> <20140122105946.GC8497@xiaoyu.lan> Message-ID: <52E0F612.1050609@eversberg.eu> Holger Hans Peter Freyther wrote: > how can someone using the MNCC know that the NITB supports the > direct RTP mode? Unless we want to introduce feature negotiation > the only way I see is to increase the version number. Or start > using major and minor numbers. dear holger, i changed the version to 4, so there is no conflict with version 3 of my handover branch. see attachment. best regards, andreas From holger at freyther.de Wed Jan 29 10:04:07 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 29 Jan 2014 11:04:07 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <1390381558-20914-6-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> Message-ID: <20140129100407.GA29223@xiaoyu.lan> On Wed, Jan 22, 2014 at 10:05:55AM +0100, Andreas Eversberg wrote: > +#define MNCC_RTP_CREATE 0x0204 > +#define MNCC_RTP_CONNECT 0x0205 > +#define MNCC_RTP_FREE 0x0206 Increase the version. We have a uint32_t for the version number and it will take a while to overflow it. > + RTP_PROXY, /* forward from BTS to BTS */ > + RTP_RECV_UPSTREAM, /* forward to L4 application */ > + RTP_RECV_L4, /* receive RTP frames from L4 application */ L4? is that the best name you can think off? > + bts = trans->conn->lchan->ts->trx->bts; > + switch (bts->type) { > + case GSM_BTS_TYPE_NANOBTS: > + case GSM_BTS_TYPE_OSMO_SYSMO: ... > + case GSM_BTS_TYPE_BS11: > + case GSM_BTS_TYPE_RBS2000: > + case GSM_BTS_TYPE_NOKIA_SITE: There are already methods for "is IP based BTS", "is E1 based BTS". Couldn't you use them here? > + /* L4 uses RTP for this transaction, we send our data via RTP, > + * otherwise we send it through MNCC interface */ > + if (msg_type == GSM_TCHF_FRAME > + || msg_type == GSM_TCHF_FRAME_EFR > + || msg_type == GSM_TCHH_FRAME > + || msg_type == GSM_TCH_FRAME_AMR > + || msg_type == GSM_BAD_FRAME) { I have seen lchan->type checks and message type checks like these as well. Could you create a predicate function that check mncc_is_audio_message(), or lchan_voice_chan? From jolly at eversberg.eu Fri Jan 31 08:02:01 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Fri, 31 Jan 2014 09:02:01 +0100 Subject: [PATCH 1/9] Complete definitions for all speech traffic frames at MNCC interface Message-ID: 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. --- openbsc/include/openbsc/mncc.h | 6 ++++-- openbsc/src/libmsc/mncc.c | 6 +++++- openbsc/src/libtrau/trau_mux.c | 2 +- openbsc/tests/trau/trau_test.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index ffc247b..c61f6b8 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -95,7 +95,9 @@ struct gsm_call { #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 -#define GSM_TCHF_BAD_FRAME 0x03ff +#define GSM_TCHH_FRAME 0x0302 +#define GSM_TCH_FRAME_AMR 0x0303 +#define GSM_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 @@ -161,7 +163,7 @@ struct gsm_data_frame { unsigned char data[0]; }; -#define MNCC_SOCK_VERSION 2 +#define MNCC_SOCK_VERSION 4 struct gsm_mncc_hello { uint32_t msg_type; uint32_t version; diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c index b484772..73db5f0 100644 --- a/openbsc/src/libmsc/mncc.c +++ b/openbsc/src/libmsc/mncc.c @@ -84,7 +84,11 @@ static struct mncc_names { {"MNCC_FRAME_DROP", 0x0202}, {"MNCC_LCHAN_MODIFY", 0x0203}, - {"GSM_TCH_FRAME", 0x0300}, + {"GSM_TCHF_FRAME", 0x0300}, + {"GSM_TCHF_FRAME_EFR", 0x0301}, + {"GSM_TCHH_FRAME", 0x0302}, + {"GSM_TCH_FRAME_AMR", 0x0303}, + {"GSM_BAD_FRAME", 0x03ff}, {NULL, 0} }; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index 7b9bac0..fd1895f 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -314,7 +314,7 @@ struct msgb *trau_decode_efr(uint32_t callref, return msg; bad_frame: - frame->msg_type = GSM_TCHF_BAD_FRAME; + frame->msg_type = GSM_BAD_FRAME; return msg; } diff --git a/openbsc/tests/trau/trau_test.c b/openbsc/tests/trau/trau_test.c index f8a48db..b95f1e8 100644 --- a/openbsc/tests/trau/trau_test.c +++ b/openbsc/tests/trau/trau_test.c @@ -57,7 +57,7 @@ void test_trau_fr_efr(unsigned char *data) msg = trau_decode_efr(1, &tf); OSMO_ASSERT(msg != NULL); frame = (struct gsm_data_frame *)msg->data; - OSMO_ASSERT(frame->msg_type == GSM_TCHF_BAD_FRAME); + OSMO_ASSERT(frame->msg_type == GSM_BAD_FRAME); msgb_free(msg); } -- 1.8.1.5 --------------060708050209070502020504 Content-Type: text/x-diff; name="0002-Use-helper-function-to-check-if-an-MNCC-frame-is-dat.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0002-Use-helper-function-to-check-if-an-MNCC-frame-is-dat.pa"; filename*1="tch" From jolly at eversberg.eu Wed Jan 22 09:05:56 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:56 +0100 Subject: [PATCH 7/9] Allow dynamic RTP payload types between application and MNCC interface In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-7-git-send-email-jolly@eversberg.eu> Since EFR/AMR/HR codecs use dynamic RTP payload, the payload type can be set. If it is set, the frame type must be set also, so OpenBSC knows what frame types are received via RTP. This modification only affects traffic beween application and MNCC interface, not the RTP traffic between OpenBSC and BTS. --- openbsc/include/openbsc/mncc.h | 2 ++ openbsc/include/openbsc/rtp_proxy.h | 2 ++ openbsc/src/libmsc/gsm_04_08.c | 2 ++ openbsc/src/libtrau/rtp_proxy.c | 57 ++++++++++++++++++++++++++----------- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index a380b8f..0a4f2ef 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -187,6 +187,8 @@ struct gsm_mncc_rtp { uint32_t callref; uint32_t ip; uint16_t port; + uint32_t payload_type; + uint32_t payload_msg_type; }; char *get_mncc_name(int value); diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index 2729f63..ae49ca5 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -74,6 +74,8 @@ struct rtp_socket { struct { struct gsm_network *net; uint32_t callref; + uint8_t payload_type; /* dynamic PT */ + int msg_type; /* message type for dynamic PT */ } receive; }; enum rtp_tx_action tx_action; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 7bb9c87..79300d1 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1758,6 +1758,8 @@ static int mncc_rtp(struct gsm_network *net, uint32_t callref, struct gsm_mncc_r mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, (struct gsm_mncc *)mncc); return -EIO; } + rs->receive.msg_type = mncc->payload_msg_type; + rs->receive.payload_type = mncc->payload_type; /* reply with local IP/port */ mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); mncc->port = ntohs(rs->rtp.sin_local.sin_port); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 2049911..ed7479d 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -106,7 +106,7 @@ struct rtp_x_hdr { #define RTP_VERSION 2 /* decode an rtp frame and create a new buffer with payload */ -static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) +static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, int msg_type) { struct msgb *new_msg; struct gsm_data_frame *frame; @@ -114,7 +114,6 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) struct rtp_x_hdr *rtpxh; uint8_t *payload; int payload_len; - int msg_type; int x_len; int amr = 0; @@ -165,9 +164,31 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) } } - switch (rtph->payload_type) { - case RTP_PT_GSM_FULL: - msg_type = GSM_TCHF_FRAME; + /* If no explicit frame type is given, select frame type from + * payload type. */ + if (!msg_type) { + switch (rtph->payload_type) { + case RTP_PT_GSM_FULL: + msg_type = GSM_TCHF_FRAME; + break; + case RTP_PT_GSM_EFR: + msg_type = GSM_TCHF_FRAME_EFR; + break; + case RTP_PT_GSM_HALF: + msg_type = GSM_TCHH_FRAME; + break; + case RTP_PT_AMR: + msg_type = GSM_TCH_FRAME_AMR; + break; + default: + DEBUGPC(DLMUX, "received RTP frame with unknown " + "payload type %d\n", rtph->payload_type); + return -EINVAL; + } + } + + switch (msg_type) { + case GSM_TCHF_FRAME: if (payload_len != RTP_LEN_GSM_FULL) { DEBUGPC(DLMUX, "received RTP full rate frame with " "payload length != %d (len = %d)\n", @@ -175,8 +196,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_GSM_EFR: - msg_type = GSM_TCHF_FRAME_EFR; + case GSM_TCHF_FRAME_EFR: if (payload_len != RTP_LEN_GSM_EFR) { DEBUGPC(DLMUX, "received RTP extended full rate frame " "with payload length != %d (len = %d)\n", @@ -184,8 +204,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_GSM_HALF: - msg_type = GSM_TCHH_FRAME; + case GSM_TCHH_FRAME: if (payload_len != RTP_LEN_GSM_HALF) { DEBUGPC(DLMUX, "received RTP half rate frame with " "payload length != 15 (len = %d)\n", @@ -193,12 +212,11 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_AMR: + case GSM_TCH_FRAME_AMR: amr = 1; break; default: - DEBUGPC(DLMUX, "received RTP frame with unknown payload " - "type %d\n", rtph->payload_type); + DEBUGPC(DLMUX, "Forced message type %x unknown\n", msg_type); return -EINVAL; } @@ -246,6 +264,10 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int payload_len; int duration; /* in samples */ int amr = 0; + uint8_t dynamic_pt = 0; + + if (rs->rx_action == RTP_RECV_L4) + dynamic_pt = rs->receive.payload_type; if (rs->tx_action != RTP_SEND_DOWNSTREAM) { /* initialize sequences */ @@ -262,17 +284,17 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) duration = RTP_GSM_DURATION; break; case GSM_TCHF_FRAME_EFR: - payload_type = RTP_PT_GSM_EFR; + payload_type = (dynamic_pt) ? : RTP_PT_GSM_EFR; payload_len = RTP_LEN_GSM_EFR; duration = RTP_GSM_DURATION; break; case GSM_TCHH_FRAME: - payload_type = RTP_PT_GSM_HALF; + payload_type = (dynamic_pt) ? : RTP_PT_GSM_HALF; payload_len = RTP_LEN_GSM_HALF; duration = RTP_GSM_DURATION; break; case GSM_TCH_FRAME_AMR: - payload_type = RTP_PT_AMR; + payload_type = (dynamic_pt) ? : RTP_PT_AMR; payload_len = frame->data[0]; duration = RTP_GSM_DURATION; amr = 1; @@ -492,7 +514,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) rc = -EINVAL; goto out_free; } - rc = rtp_decode(msg, rs->receive.callref, &new_msg); + rc = rtp_decode(msg, rs->receive.callref, &new_msg, 0); if (rc < 0) goto out_free; msgb_free(msg); @@ -508,7 +530,8 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) rc = ENOTSUP; goto out_free; } - rc = rtp_decode(msg, rs->receive.callref, &new_msg); + rc = rtp_decode(msg, rs->receive.callref, &new_msg, + rs->receive.msg_type); if (rc < 0) goto out_free; msgb_free(msg); -- 1.8.1.5 From jolly at eversberg.eu Wed Jan 22 09:05:57 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:57 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-8-git-send-email-jolly@eversberg.eu> The RTP stream is generated or forwarded by OpenBSC to nanoBTS. Due to switching of streams (hold/retrieve call), packet loss or even stalling of sender's process, the time stamp must be corrected. If outdated packets are received, they get dropped. --- openbsc/src/libtrau/rtp_proxy.c | 80 ++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index ed7479d..3e6c462 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -236,6 +236,12 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in return 0; } +#define USEC_1S 1000000 +#define USEC_10MS 10000 +#define USEC_20MS 20000 +#define SAMPLES_1S 8000 +#define USEC_SAMPLE 125 + /* "to - from" */ static void tv_difference(struct timeval *diff, const struct timeval *from, const struct timeval *__to) @@ -244,13 +250,60 @@ static void tv_difference(struct timeval *diff, const struct timeval *from, if (to->tv_usec < from->tv_usec) { to->tv_sec -= 1; - to->tv_usec += 1000000; + to->tv_usec += USEC_1S; } diff->tv_usec = to->tv_usec - from->tv_usec; diff->tv_sec = to->tv_sec - from->tv_sec; } +/* add sec,usec to tv */ +static void tv_add(struct timeval *tv, int sec, int usec) +{ + + if (usec < 0) + usec += USEC_1S; + tv->tv_sec += sec; + tv->tv_usec += usec; + if (tv->tv_usec >= USEC_1S) { + tv->tv_sec++; + tv->tv_usec -= USEC_1S; + } +} + +static int correct_timestamp(struct rtp_socket *rs, int duration) +{ + struct timeval tv, tv_diff; + long int usec_diff, frame_diff; + + gettimeofday(&tv, NULL); + tv_difference(&tv_diff, &rs->transmit.last_tv, &tv); + tv_add(&rs->transmit.last_tv, 0, USEC_20MS); + + usec_diff = tv_diff.tv_sec * USEC_1S + tv_diff.tv_usec; + frame_diff = ((usec_diff + (USEC_10MS)) / USEC_20MS); /* round */ + + if (abs(frame_diff - 1) > 1) { + long int frame_diff_excess = frame_diff - 1; + long int sample_diff_excess = frame_diff_excess * duration; + + /* correct last_tv */ + tv_add(&rs->transmit.last_tv, sample_diff_excess / SAMPLES_1S, + (sample_diff_excess % SAMPLES_1S) * USEC_SAMPLE); + /* drop frame, if time stamp is in the past */ + if (frame_diff_excess < 0) + return -1; + LOGP(DLMUX, LOGL_NOTICE, + "Correcting timestamp difference of %ld frames " + "(to %s)\n", frame_diff_excess, + (rs->rx_action == RTP_RECV_L4) ? "app" : "BTS"); + rs->transmit.sequence += frame_diff_excess; + rs->transmit.timestamp += sample_diff_excess; + } + + return 0; +} + /*! \brief encode and send a rtp frame * \param[in] rs RTP socket through which we shall send * \param[in] frame GSM RTP frame to be sent @@ -265,6 +318,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int duration; /* in samples */ int amr = 0; uint8_t dynamic_pt = 0; + int rc; if (rs->rx_action == RTP_RECV_L4) dynamic_pt = rs->receive.payload_type; @@ -275,6 +329,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) rs->transmit.ssrc = rand(); rs->transmit.sequence = random(); rs->transmit.timestamp = random(); + gettimeofday(&rs->transmit.last_tv, NULL); } switch (frame->msg_type) { @@ -313,26 +368,9 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) return -EINVAL; } - { - struct timeval tv, tv_diff; - long int usec_diff, frame_diff; - - gettimeofday(&tv, NULL); - tv_difference(&tv_diff, &rs->transmit.last_tv, &tv); - rs->transmit.last_tv = tv; - - usec_diff = tv_diff.tv_sec * 1000000 + tv_diff.tv_usec; - frame_diff = (usec_diff / 20000); - - if (abs(frame_diff) > 1) { - long int frame_diff_excess = frame_diff - 1; - - LOGP(DLMUX, LOGL_NOTICE, - "Correcting frame difference of %ld frames\n", frame_diff_excess); - rs->transmit.sequence += frame_diff_excess; - rs->transmit.timestamp += frame_diff_excess * duration; - } - } + rc = correct_timestamp(rs, duration); + if (rc) + return 0; if (frame->msg_type == GSM_BAD_FRAME) return 0; -- 1.8.1.5 From peter at stuge.se Wed Jan 22 10:21:50 2014 From: peter at stuge.se (Peter Stuge) Date: Wed, 22 Jan 2014 11:21:50 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <1390381558-20914-8-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> Message-ID: <20140122102150.3862.qmail@stuge.se> Andreas Eversberg wrote: > +/* add sec,usec to tv */ > +static void tv_add(struct timeval *tv, int sec, int usec) > +{ > + > + if (usec < 0) > + usec += USEC_1S; Doesn't this also need to do sec--; ? > + tv->tv_sec += sec; > + tv->tv_usec += usec; > + if (tv->tv_usec >= USEC_1S) { > + tv->tv_sec++; > + tv->tv_usec -= USEC_1S; > + } > +} Consider changing the second if() to while(), so that the function works correctly also when adding several seconds using only the usec parameter. Very nice use of defines! They make for excellent readability. //Peter From andreas at eversberg.eu Thu Jan 23 10:44:34 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 11:44:34 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <20140122102150.3862.qmail@stuge.se> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> Message-ID: <52E0F292.3040100@eversberg.eu> Peter Stuge wrote: >> + if (usec < 0) >> >+ usec += USEC_1S; > Doesn't this also need to do sec--; ? > > >> >+ tv->tv_sec += sec; >> >+ tv->tv_usec += usec; >> >+ if (tv->tv_usec >= USEC_1S) { >> >+ tv->tv_sec++; >> >+ tv->tv_usec -= USEC_1S; >> >+ } >> >+} > Consider changing the second if() to while(), so that the function > works correctly also when adding several seconds using only the usec > parameter. dear peter, thanx for looking at the patch. i fixed the missing "sec--" and added while loops. see attachment. best regards, andreas From andreas at eversberg.eu Thu Jan 23 10:53:55 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 11:53:55 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <20140122102150.3862.qmail@stuge.se> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> Message-ID: <52E0F4C3.6070106@eversberg.eu> sorry, wrong attachment in my last mail. here is the correct one. From jerlbeck at sysmocom.de Thu Jan 30 10:58:55 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 11:58:55 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <52E0F4C3.6070106@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> <52E0F4C3.6070106@eversberg.eu> Message-ID: <52EA306F.4000002@sysmocom.de> Dear Andreas, On 23.01.2014 11:53, Andreas Eversberg wrote: > > 0008-Fixed-nanoBTS-delay-problems-if-RTP-stream-jitters-t.patch > > @@ -244,13 +250,62 @@ static void tv_difference(struct timeval *diff, const struct timeval *from, ... Is there a reason why you are not using the BSD macros timersub and timeradd (beside the new support for denormalized usec values)? > > +/* add sec,usec to tv */ > +static void tv_add(struct timeval *tv, int sec, int usec) > +{ > + > + while (usec < 0) { > + usec += USEC_1S; > + sec--; > + } > + tv->tv_sec += sec; > + tv->tv_usec += usec; > + while (tv->tv_usec >= USEC_1S) { > + tv->tv_sec++; > + tv->tv_usec -= USEC_1S; > + } > +} I'm not sure whether it is a good idea to use while loops in this case since CPU usage is O(N) of the usec value. Wouldn't it be more convenient to have a function tv_add_us(tv, usec) instead that does the div/mod stuff to a temporary timeval and then just calls timeradd()? Cheers Jacob From peter at stuge.se Thu Jan 30 15:43:05 2014 From: peter at stuge.se (Peter Stuge) Date: Thu, 30 Jan 2014 16:43:05 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <52EA306F.4000002@sysmocom.de> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> <52E0F4C3.6070106@eversberg.eu> <52EA306F.4000002@sysmocom.de> Message-ID: <20140130154305.22908.qmail@stuge.se> Jacob Erlbeck wrote: > > +/* add sec,usec to tv */ > > +static void tv_add(struct timeval *tv, int sec, int usec) > > +{ > > + > > + while (usec < 0) { > > + usec += USEC_1S; > > + sec--; > > + } > > + tv->tv_sec += sec; > > + tv->tv_usec += usec; > > + while (tv->tv_usec >= USEC_1S) { > > + tv->tv_sec++; > > + tv->tv_usec -= USEC_1S; > > + } > > +} > > I'm not sure whether it is a good idea to use while loops in this case > since CPU usage is O(N) of the usec value. Remember that N>1 only with very small or very large usec values, which I guess will be a corner case since it wasn't handled before? > Wouldn't it be more convenient to have a function tv_add_us(tv, usec) > instead that does the div/mod stuff to a temporary timeval and then > just calls timeradd()? Is there a machine where div/mod is actually more efficient than a small number of iterations around a loop? :) Is this a hot path? Then I think it makes sense to optimize harder for performance rather than for readability. But compilers are good at that too.. //Peter From jerlbeck at sysmocom.de Thu Jan 30 20:00:17 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:00:17 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <20140130154305.22908.qmail@stuge.se> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> <52E0F4C3.6070106@eversberg.eu> <52EA306F.4000002@sysmocom.de> <20140130154305.22908.qmail@stuge.se> Message-ID: <52EAAF51.9020203@sysmocom.de> On 30.01.2014 16:43, Peter Stuge wrote: > Jacob Erlbeck wrote: >>> +/* add sec,usec to tv */ >>> +static void tv_add(struct timeval *tv, int sec, int usec) >>> +{ >>> + >>> + while (usec < 0) { >>> + usec += USEC_1S; >>> + sec--; >>> + } >>> + tv->tv_sec += sec; >>> + tv->tv_usec += usec; >>> + while (tv->tv_usec >= USEC_1S) { >>> + tv->tv_sec++; >>> + tv->tv_usec -= USEC_1S; >>> + } >>> +} >> >> I'm not sure whether it is a good idea to use while loops in this case >> since CPU usage is O(N) of the usec value. > > Remember that N>1 only with very small or very large usec values, > which I guess will be a corner case since it wasn't handled before? I think the question here is, do I want have a generic function that could be used in other places, too? If yes, I strongly advice to take into account that bad things could happen here (e.g. due to bugs delivering broken values for usec), eventually causing very-hard-to-diagnose latency problems. If you first check for out-of-range usecs, hint it with something like UNLIKELY() and do the div/mod in that case only. That's probably slightly faster than the while approach if most of the usecs are within 0..999999 and has still an upper bound. Or are we looking at the few applications already part of the patch, which would not have any advantage of allowing out of range usecs. > > Is there a machine where div/mod is actually more efficient than a > small number of iterations around a loop? :) That depends on 'small'. But sheer performance (throughput) is not always the most important, sometimes it's predictability, latency, and maintainability. And throughput at the cost of the others should be considered very carefully! >> Wouldn't it be more convenient to have a function tv_add_us(tv, usec) >> instead that does the div/mod stuff to a temporary timeval and then >> just calls timeradd()? Let's assume I had an implementation like (no it's not C) void tv_add_us(tv, usec) { struct timeval foo; foo.tv_sec = usec / 1000000; foo.tv_usec = usec % 1000000; timeradd(tv, &foo, tv); } Looking at the applications of the function: tv_add(&rs->transmit.last_tv, 0, USEC_20MS); tv_add(&rs->transmit.last_tv, sample_diff_excess / SAMPLES_1S, (sample_diff_excess % SAMPLES_1S) * USEC_SAMPLE); Which I then would write as tv_add_us(&rs->transmit.last_tv, USEC_20MS); tv_add_us(&rs->transmit.last_tv, sample_diff_excess * USEC_SAMPLE); And thanks to inlining the div/mod would vanish completely in the first case and would be without extra cost in the second. So no performance penalty but much better readability. > Is this a hot path? Then I think it makes sense to optimize harder > for performance rather than for readability. But compilers are good > at that too.. I'd rather go for readability by default until profiling tells me otherwise. Some well-intentioned hand optimizations lead sometimes to worse performance if the prevent the compiler from doing better optimizations. So on some platforms a branch taken can be more expensive than a div/mod. And did you understand the second application of tv_add() at first sight? It is correct but that is not obvious IMO. Jacob From holger at freyther.de Wed Jan 22 11:02:40 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 22 Jan 2014 12:02:40 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <1390381558-20914-8-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> Message-ID: <20140122110240.GD8497@xiaoyu.lan> On Wed, Jan 22, 2014 at 10:05:57AM +0100, Andreas Eversberg wrote: > The RTP stream is generated or forwarded by OpenBSC to nanoBTS. Due to > switching of streams (hold/retrieve call), packet loss or even stalling > of sender's process, the time stamp must be corrected. If outdated > packets are received, they get dropped. Can you please use the rtp state/replay code to show this specific issue? From Jacob's latest experiment the nanoBTS software only appears to have issues when the same timestamp is sent twice or the sample delta is not a multiple of 160. The replaying code and the generation of rtp_headers can be found in the contrib/rtp directory. holger From andreas at eversberg.eu Thu Jan 23 11:00:50 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 12:00:50 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <20140122110240.GD8497@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122110240.GD8497@xiaoyu.lan> Message-ID: <52E0F662.7030304@eversberg.eu> Holger Hans Peter Freyther wrote: > The replaying code and the generation of rtp_headers can be found in > the contrib/rtp directory. is there any tutorial about what is does and on how to use it? From jolly at eversberg.eu Wed Jan 22 09:05:58 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 22 Jan 2014 10:05:58 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <1390381558-20914-9-git-send-email-jolly@eversberg.eu> When reading from RTP socket, the first read() may fail right after connecting to remote socket. Subsequent read() will work as it should. I have not discovered why this read fails, but I don't see any reason why we should stop reading, just because one read() fails at the beginning. --- openbsc/src/libtrau/rtp_proxy.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 3e6c462..8b19c93 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -501,10 +501,8 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) return -ENOMEM; rc = read(rss->bfd.fd, msg->data, RTP_ALLOC_SIZE); - if (rc <= 0) { - rss->bfd.when &= ~BSC_FD_READ; + if (rc <= 0) return rc; - } msgb_put(msg, rc); -- 1.8.1.5 From peter at stuge.se Wed Jan 22 10:24:06 2014 From: peter at stuge.se (Peter Stuge) Date: Wed, 22 Jan 2014 11:24:06 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <1390381558-20914-9-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> Message-ID: <20140122102406.4100.qmail@stuge.se> Andreas Eversberg wrote: > When reading from RTP socket, the first read() may fail right after > connecting to remote socket. Subsequent read() will work as it should. > > I have not discovered why this read fails, but I don't see any reason > why we should stop reading, just because one read() fails at the > beginning. What is errno set to when this failure happens? How to handle read() failures should probably depend on exactly what the failure is, ie. might need testing errno for known benign values and letting anything else cause a more severe error which bubbles up the stack. //Peter From andreas at eversberg.eu Thu Jan 23 10:57:00 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 11:57:00 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <20140122102406.4100.qmail@stuge.se> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> <20140122102406.4100.qmail@stuge.se> Message-ID: <52E0F57C.1060407@eversberg.eu> Peter Stuge wrote: > What is errno set to when this failure happens? > > How to handle read() failures should probably depend on exactly what > the failure is, ie. might need testing errno for known benign values > and letting anything else cause a more severe error which bubbles up > the stack. i did some tests. it actually happens when the remote peer has not yet bound the RTP socket, so the local peer receives a "connection refused". i updated the patch, see attachment. From holger at freyther.de Thu Jan 23 11:36:02 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 23 Jan 2014 12:36:02 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <52E0F57C.1060407@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> <20140122102406.4100.qmail@stuge.se> <52E0F57C.1060407@eversberg.eu> Message-ID: <20140123113602.GE8126@xiaoyu.lan> On Thu, Jan 23, 2014 at 11:57:00AM +0100, Andreas Eversberg wrote: > + if (errno == 111) again, please use fewer magic numbers. Use ECONNREFUSED then. > + DEBUGPC(DLMUX, "Read of RTP socket (%p) failed (errno %d)\n", > + rs, errno); Please consider using strerror next to the errno From andreas at eversberg.eu Thu Jan 23 13:32:42 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 23 Jan 2014 14:32:42 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <20140123113602.GE8126@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> <20140122102406.4100.qmail@stuge.se> <52E0F57C.1060407@eversberg.eu> <20140123113602.GE8126@xiaoyu.lan> Message-ID: <52E119FA.5030108@eversberg.eu> Holger Hans Peter Freyther wrote: >> + if (errno == 111) > again, please use fewer magic numbers. Use ECONNREFUSED then. > >> >+ DEBUGPC(DLMUX, "Read of RTP socket (%p) failed (errno %d)\n", >> >+ rs, errno); > Please consider using strerror next to the errno > ok, here it is. From ciaby at autistici.org Tue Jan 28 23:34:53 2014 From: ciaby at autistici.org (Ciaby) Date: Tue, 28 Jan 2014 17:34:53 -0600 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <52E119FA.5030108@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> <20140122102406.4100.qmail@stuge.se> <52E0F57C.1060407@eversberg.eu> <20140123113602.GE8126@xiaoyu.lan> <52E119FA.5030108@eversberg.eu> Message-ID: <52E83E9D.70506@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 01/23/2014 07:32 AM, Andreas Eversberg wrote: > ok, here it is. So, what's the timeline for these patches to be integrated into the master branch? There are some specific things in there (half-rate support, AMR support, rtp-bridge) which could be very handy to us (Rhizomatica) both in terms of network capacity and also sound quality (at the moment we are routing everything to LCR, which means a GSM<->PCMA<->GSM codec conversion even on internal calls). Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREKAAYFAlLoPpgACgkQC30ZhxNccpEDKwEAmGYdMeWvugoRPnW4QTMTfYaj cPduR9Bo+ipmDtN7pQ4A/14k6ZgRH6l73AJA6AqmNmMhxILgOSGRIAoP8PNCnXRv =bBw9 -----END PGP SIGNATURE----- From holger at freyther.de Wed Jan 29 09:58:15 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 29 Jan 2014 10:58:15 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <52E83E9D.70506@autistici.org> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-9-git-send-email-jolly@eversberg.eu> <20140122102406.4100.qmail@stuge.se> <52E0F57C.1060407@eversberg.eu> <20140123113602.GE8126@xiaoyu.lan> <52E119FA.5030108@eversberg.eu> <52E83E9D.70506@autistici.org> Message-ID: <20140129095815.GC21513@xiaoyu.lan> On Tue, Jan 28, 2014 at 05:34:53PM -0600, Ciaby wrote: Hi, > > ok, here it is. > So, what's the timeline for these patches to be integrated into the > master branch? There are some specific things in there (half-rate > support, AMR support, rtp-bridge) which could be very handy to us > (Rhizomatica) both in terms of network capacity and also sound quality > (at the moment we are routing everything to LCR, which means a > GSM<->PCMA<->GSM codec conversion even on internal calls). the answer is as time permits. As you see with the responses there are various things that are not right with them and as a maintainer it is frustrating to have to start at zero at every new patch. From holger at freyther.de Sun Jan 26 07:49:18 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 08:49:18 +0100 Subject: [PATCH 1/9] Add function to update TRAU muxer after assignment or handover In-Reply-To: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> Message-ID: <20140126074918.GN9524@xiaoyu.lan> On Wed, Jan 22, 2014 at 10:05:50AM +0100, Andreas Eversberg wrote: > - /* in case, we don't have a RTP socket yet, we note this > - * in the transaction and try later */ > + /* in case, we don't have a RTP socket yet, we try later */ > case GSM_BTS_TYPE_NOKIA_SITE: > + /* in case we don't have a TCH with correct mode, we try later */ Please attempt to write comments in a way that one can understand them in a year later. What will be tried later? But actually try for me means that the code would actually execute a deferred action while here it will simply react to another function call. PLease update the patch. From andreas at eversberg.eu Sun Jan 26 08:57:03 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sun, 26 Jan 2014 09:57:03 +0100 Subject: [PATCH 1/9] Add function to update TRAU muxer after assignment or handover In-Reply-To: <20140126074918.GN9524@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <20140126074918.GN9524@xiaoyu.lan> Message-ID: <52E4CDDF.4060300@eversberg.eu> Holger Hans Peter Freyther wrote: > Please attempt to write comments in a way that one can understand them > in a year later. What will be tried later? But actually try for me means > that the code would actually execute a deferred action while here it will > simply react to another function call. > > PLease update the patch. ok, here is the updated patch. From holger at freyther.de Sun Jan 26 21:32:12 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 22:32:12 +0100 Subject: [PATCH 1/9] Add function to update TRAU muxer after assignment or handover In-Reply-To: <52E4CDDF.4060300@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <20140126074918.GN9524@xiaoyu.lan> <52E4CDDF.4060300@eversberg.eu> Message-ID: <20140126213212.GD4274@xiaoyu.lan> On Sun, Jan 26, 2014 at 09:57:03AM +0100, Andreas Eversberg wrote: > Holger Hans Peter Freyther wrote: > >Please attempt to write comments in a way that one can understand them > >in a year later. What will be tried later? But actually try for me means > >that the code would actually execute a deferred action while here it will > >simply react to another function call. > + /* In case, we don't have a RTP socket to the BTS yet, we try > + * later when the socket has been created and connected. */ > if (!lchan->abis_ip.rtp_socket) { > - trans->tch_recv = enable; sorry to nitpick but these things matter when people read someone else's code in order to understand how things work. Right now I am not able to understand "what" will be tried later? Maybe something like this: /* In case we don't have a RTP socket to the BTS yet, the code * can not connect the sockets and will return. This method will * be called for the next NET->BTS frame and once audio is connected * from the BTS. */ or something along the lines. > + /* In case we don't have a TCH with correct mode, we try later > + * after assignment or handover is complete. This is performed > + * by switch_trau_mux() then. */ Similar. s/try/will be done/ From andreas at eversberg.eu Mon Jan 27 09:19:14 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 27 Jan 2014 10:19:14 +0100 Subject: [PATCH 1/9] Add function to update TRAU muxer after assignment or handover In-Reply-To: <20140126213212.GD4274@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <20140126074918.GN9524@xiaoyu.lan> <52E4CDDF.4060300@eversberg.eu> <20140126213212.GD4274@xiaoyu.lan> Message-ID: <52E62492.7010208@eversberg.eu> Holger Hans Peter Freyther wrote: > sorry to nitpick but these things matter when people read someone else's > code in order to understand how things work. Right now I am not able to > understand "what" will be tried later? dear holger, no problem. i thought it was clear enough, by reading further comments in the code. in the attachment i describes "what" and "when". i hope that it is clear enough now. best regards, andreas From dchardware at gmail.com Thu Jan 23 11:33:55 2014 From: dchardware at gmail.com (Sipos Csaba) Date: Thu, 23 Jan 2014 12:33:55 +0100 Subject: GPRS, EDGE support Message-ID: <1529289201.20140123123355@freemail.hu> Hi Guys, I just wanted to ask a few questions about packet data availability/support, because I did not find the specifics on the site. 1. Is there a working GPRS/EDGE implementation in the moment? If not, what is the plan or the state of the development process? 2. Which hardware should I buy, if I want to play with GPRS/EDGE? I am thinking about USRP or BladeRF, but maybe there is a better alternative. I am willing to spend more in order to get a more future proof unit (for example: to have a unit which is capable of doing EDGE if and when it is going to be supported). 3. This is not related to packet data. I wonder if I buy a USRP unit , it is possible to configure and use one USRP device with more than one TRX? In general, I think a lot of people are interested in packet data and OpenBSC/OpenBTS, it would be nice to clarify these informations on the site. BR, Csaba From don at 00100100.net Thu Jan 23 17:04:43 2014 From: don at 00100100.net (Don Fanning) Date: Thu, 23 Jan 2014 09:04:43 -0800 Subject: GPRS, EDGE support In-Reply-To: <1529289201.20140123123355@freemail.hu> References: <1529289201.20140123123355@freemail.hu> Message-ID: There has been a working GPRS stack for a while now: http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS As for USRP or OpenBTS, I cannot comment upon having never used either platform. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Thu Jan 23 18:12:34 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Thu, 23 Jan 2014 19:12:34 +0100 Subject: GPRS, EDGE support In-Reply-To: <1773387428.20140123183717@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> Message-ID: <001201cf1866$b1604180$1420c480$@schmid.xxx> OpenBTS supports GPRS, but at least for me it does not work very reliably, I consider this only a proof of concept. While voice/SMS range is up to 200m, GPRS breaks down after 5m (!) distance, and the connection stalls after a while, requiring a restart of OpenBTS. I am using an USRP1 with WBX board. Ralph. From: openbsc-bounces at lists.osmocom.org [mailto:openbsc-bounces at lists.osmocom.org] On Behalf Of Sipos Csaba Sent: Thursday, 23 January, 2014 18:37 To: Don Fanning Cc: openbsc at lists.osmocom.org Subject: Re[2]: GPRS, EDGE support Hi Don, Thanks for the answer. THe problem with nanobts that it is unaccessible, and even when it turns up on ebay, it costs a fortune. I'd rather pay that fortune for an USRP or half that fortune for a bladerf, and I will have an SDR which I can use not only as a BTS. So, at the moment GPRS/EDGE is only possible with nanoBTS? What about USRP or BladeRF running OpenBTS? BR, Csaba There has been a working GPRS stack for a while now: http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS As for USRP or OpenBTS, I cannot comment upon having never used either platform. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dburgess at jcis.net Thu Jan 23 22:00:55 2014 From: dburgess at jcis.net (David A. Burgess) Date: Fri, 24 Jan 2014 00:00:55 +0200 Subject: GPRS, EDGE support In-Reply-To: <001201cf1866$b1604180$1420c480$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> <001201cf1866$b1604180$1420c480$@schmid.xxx> Message-ID: Ralph - I realize this is off topic, but if you have such severe range differences between CS and PS performance, it is probably a GPRS uplink power control configuration problem. Note: I am no longer affiliated with Range Networks, just trying to be helpful. ? David On Jan 23, 2014, at 20:12, Ralph A. Schmid, dk5ras wrote: > OpenBTS supports GPRS, but at least for me it does not work very reliably, I consider this only a proof of concept. While voice/SMS range is up to 200m, GPRS breaks down after 5m (!) distance, and the connection stalls after a while, requiring a restart of OpenBTS. I am using an USRP1 with WBX board. > > Ralph. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Fri Jan 24 04:33:50 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Fri, 24 Jan 2014 05:33:50 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> <001201cf1866$b1604180$1420c480$@schmid.xxx> Message-ID: <005d01cf18bd$7aebe800$70c3b800$@schmid.xxx> Yes, this also is my idea, but configuration of this is somehow difficult, and I do not get clear, reliable results from changing the parameters. I have noticed that you're not a "Ranger" anymore; hopefully your broad knowledge is still available for the GSM world :) Ralph. From: David A. Burgess [mailto:dburgess at jcis.net] Sent: Thursday, 23 January, 2014 23:01 To: Ralph A. Schmid, dk5ras Cc: metro4; Don Fanning; openbsc at lists.osmocom.org Subject: Re: GPRS, EDGE support Ralph - I realize this is off topic, but if you have such severe range differences between CS and PS performance, it is probably a GPRS uplink power control configuration problem. Note: I am no longer affiliated with Range Networks, just trying to be helpful. - David On Jan 23, 2014, at 20:12, Ralph A. Schmid, dk5ras wrote: OpenBTS supports GPRS, but at least for me it does not work very reliably, I consider this only a proof of concept. While voice/SMS range is up to 200m, GPRS breaks down after 5m (!) distance, and the connection stalls after a while, requiring a restart of OpenBTS. I am using an USRP1 with WBX board. Ralph. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Thu Jan 23 23:32:32 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 24 Jan 2014 03:32:32 +0400 Subject: GPRS, EDGE support In-Reply-To: <431257278.20140123220121@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> <001201cf1866$b1604180$1420c480$@schmid.xxx> <431257278.20140123220121@freemail.hu> Message-ID: Csaba, We use UmTRX routinely to develop GPRS code for OpenBSC and it works well. I can't say much about other SDR equipment, but we have some timing related bugs with USRP1 based devices of one of our customers. Regarding the official OpenBTS GPRS code - we've never tried to run it, but looking into the code, it lacks quite a few features the OpenBSC implementation has. On Fri, Jan 24, 2014 at 1:01 AM, Sipos Csaba wrote: > Thanks for the info! > > > At least now I know, that the GPRS/EDGE is part of the OpenBTS code, so > any hardware is OK for packet data which can run OpenBTS. That is good news. > > > Anyway, it is just an educated guess, but don't you think your problem > with GPRS is related to timing? My experience with real life networks > clearly shows that even a slight timing related problem or inaccuracy can > led to something like that. > > > My other experience is with R&S CMW500, which I used with a little > external antenna and encountered the same problem. After a few meters even > the voice calls started to drop with -60 RSSI. The reason was obvious: the > device lacks any filters on the input chain (it is designed for production > mode), and when all the received RF energy hits the receiver from all the > bands, it causes problems like that. And the packet data was way more > sensitive to this than voice calls. After installing proper filters, the > problem is gone. > > > BR, > > Csaba > > > > OpenBTS supports GPRS, but at least for me it does not work very > reliably, I consider this only a proof of concept. While voice/SMS range is > up to 200m, GPRS breaks down after 5m (!) distance, and the connection > stalls after a while, requiring a restart of OpenBTS. I am using an USRP1 > with WBX board. > > > > Ralph. > -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Fri Jan 24 04:29:16 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Fri, 24 Jan 2014 05:29:16 +0100 Subject: GPRS, EDGE support In-Reply-To: <431257278.20140123220121@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> <001201cf1866$b1604180$1420c480$@schmid.xxx> <431257278.20140123220121@freemail.hu> Message-ID: <005001cf18bc$d7f79900$87e6cb00$@schmid.xxx> Well, at least voice and SMS is not affected and works just great. GPRS uses only an open power control, no closed loop, maybe it has to do with this? At the moment I do not have other hardware for comparison, so digging deeper into this may be not so useful. The issue is discussed on the OpenBTS mailing list, with no clear results at the moment. Ralph. From: Sipos Csaba [mailto:dchardware at gmail.com] Sent: Thursday, 23 January, 2014 22:01 To: Ralph A. Schmid, dk5ras Cc: 'Don Fanning'; openbsc at lists.osmocom.org Subject: Re[4]: GPRS, EDGE support Thanks for the info! At least now I know, that the GPRS/EDGE is part of the OpenBTS code, so any hardware is OK for packet data which can run OpenBTS. That is good news. Anyway, it is just an educated guess, but don't you think your problem with GPRS is related to timing? My experience with real life networks clearly shows that even a slight timing related problem or inaccuracy can led to something like that. My other experience is with R&S CMW500, which I used with a little external antenna and encountered the same problem. After a few meters even the voice calls started to drop with -60 RSSI. The reason was obvious: the device lacks any filters on the input chain (it is designed for production mode), and when all the received RF energy hits the receiver from all the bands, it causes problems like that. And the packet data was way more sensitive to this than voice calls. After installing proper filters, the problem is gone. BR, Csaba OpenBTS supports GPRS, but at least for me it does not work very reliably, I consider this only a proof of concept. While voice/SMS range is up to 200m, GPRS breaks down after 5m (!) distance, and the connection stalls after a while, requiring a restart of OpenBTS. I am using an USRP1 with WBX board. Ralph. -------------- next part -------------- An HTML attachment was scrubbed... URL: From don at 00100100.net Fri Jan 24 16:20:33 2014 From: don at 00100100.net (Don Fanning) Date: Fri, 24 Jan 2014 08:20:33 -0800 Subject: GPRS, EDGE support In-Reply-To: <1773387428.20140123183717@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <1773387428.20140123183717@freemail.hu> Message-ID: Again, I can't speak to the USRP or BladeRF. OpenBTS is a completely different project with a completely different scope. The projects share very little of a common code base therefore I would consider it incompatible as architecturally they are night and day. OpenBTS is a hack of GSM protocol while OpenBSC is a emulation of the GSM/GPRS mobile network infrastructure. If I had to recommend available compatible hardware, I would suggest community based hardware like Harald's own sysmoBTS or Alexander's UmTRX. On Thu, Jan 23, 2014 at 9:37 AM, Sipos Csaba wrote: > Hi Don, > > > Thanks for the answer. > > > THe problem with nanobts that it is unaccessible, and even when it turns > up on ebay, it costs a fortune. > > > I'd rather pay that fortune for an USRP or half that fortune for a > bladerf, and I will have an SDR which I can use not only as a BTS. > > > So, at the moment GPRS/EDGE is only possible with nanoBTS? What about USRP > or BladeRF running OpenBTS? > > > BR, > > Csaba > > > > There has been a working GPRS stack for a while now: > > http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS > > > As for USRP or OpenBTS, I cannot comment upon having never used either > platform. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Fri Jan 24 08:32:57 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 24 Jan 2014 09:32:57 +0100 Subject: GPRS, EDGE support In-Reply-To: <1529289201.20140123123355@freemail.hu> References: <1529289201.20140123123355@freemail.hu> Message-ID: <20140124083257.GC4910@xiaoyu.lan> On Thu, Jan 23, 2014 at 12:33:55PM +0100, Sipos Csaba wrote: > Hi Guys, Hi, > 1. Is there a working GPRS/EDGE implementation in the moment? If not, > what is the plan or the state of the development process? the sysmoBTS dsp supports all GPRS and EDGE coding schemes. The osmo-pcu currently only supports GPRS RLC frames. > 2. Which hardware should I buy, if I want to play with GPRS/EDGE? I am > thinking about USRP or BladeRF, but maybe there is a better > alternative. I am willing to spend more in order to get a more > future proof unit (for example: to have a unit which is capable of > doing EDGE if and when it is going to be supported). Nobody to command you. Naturally we do the development on the sysmoBTS and when you have a look at the osmo-pcu git repository you see which entity is the most active one. ;) cheers holger From dchardware at gmail.com Fri Jan 24 09:59:51 2014 From: dchardware at gmail.com (Sipos Csaba) Date: Fri, 24 Jan 2014 10:59:51 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140124083257.GC4910@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> Message-ID: <1023409662.20140124105951@freemail.hu> Hi Holger, > Nobody to command you. Naturally we do the development on the sysmoBTS > and when you have a look at the osmo-pcu git repository you see which > entity is the most active one. ;) I want to be commanded :-) or at least guided towards the best possible choice. I need to choose a device for educational purposes, that is capable for packet data with OpenBSC/OpenBTS. This will going to extend our current 2G setup which currently has 3 Nokia Site family units with OpenBSC. So lets see if I get this correctly: For GPRS/EDGE to work I need to choose from the following HW: - USRP2 (I also heard that USRP1 has timing problems, but as I know, these problems are fixed in USRP2 and the networked series?) - UmTRX - BladeRF (according to them, they are quite close to running OpenBTS) - SysmoBTS - NanoBTS Correct? I am more convinced to buy an SDR like device, because we can use that for other stuff too. But if you are telling me, that for example SysmoBTS or NanoBTS runs the GRPS stack better, compared to UmTRX or USRP2, than I can respect that. I also want to ask one more time, if it is possible to run multiple TRXes on one SDR like device which has enough processing power and bandwidth? Did someone already tried this? Or it is not even possible? Anyway, I thought that the GPRS support is part of the OpenBTS development, and any hardware that can run OpenBTS is also capable of doing GPRS, but it is clear, that there are differences in the level of support, even between SDR like devices. I still think that it would be nice, to clarify all this packet data related stuff on the site. BR,Csaba From holger at freyther.de Fri Jan 24 12:29:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 24 Jan 2014 13:29:03 +0100 Subject: GPRS, EDGE support In-Reply-To: <1023409662.20140124105951@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> Message-ID: <20140124122903.GB10034@xiaoyu.lan> On Fri, Jan 24, 2014 at 10:59:51AM +0100, Sipos Csaba wrote: > Hi Holger, Hi! > I need to choose a device for educational purposes, that is capable > for packet data with OpenBSC/OpenBTS. This will going to extend our > current 2G setup which currently has 3 Nokia Site family units with > OpenBSC. It all depends and being associated with sysmocom i am biased too. SDRs provide the greatest flexibility but unless you have specific RF filters in your frontend you will not pass the harmonized norms of the European Union for GSM. sysmoBTS has a closed source DSP/FPGA image/bitmask. This means you can't easily look at the channel coding/burst creation. So there is reduced flexibility. The benefit is that a single unit can host BTS+PCU+NITB. nanoBTS is a completely closed source product. Their GPRS stack has reliability issues and they try to hide things (e.g. changing the password for their telnet interface). There is no flexibility. > Correct? From peter at stuge.se Fri Jan 24 20:29:21 2014 From: peter at stuge.se (Peter Stuge) Date: Fri, 24 Jan 2014 21:29:21 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140124122903.GB10034@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: <20140124202921.2029.qmail@stuge.se> Holger Hans Peter Freyther wrote: > nanoBTS is a completely closed source product. Their GPRS stack > has reliability issues Just a note that I've heard that nanoBTS GPRS is perfectly reliable with the ipaccess BSC. I haven't seen it myself though. Maybe some day there will be some analysis of what is actually different. //Peter From holger at freyther.de Sat Jan 25 10:00:31 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 25 Jan 2014 11:00:31 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140124202921.2029.qmail@stuge.se> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140124202921.2029.qmail@stuge.se> Message-ID: <20140125100031.GD9524@xiaoyu.lan> On Fri, Jan 24, 2014 at 09:29:21PM +0100, Peter Stuge wrote: > > nanoBTS is a completely closed source product. Their GPRS stack > > has reliability issues > > Just a note that I've heard that nanoBTS GPRS is perfectly reliable > with the ipaccess BSC. I haven't seen it myself though. Maybe some > day there will be some analysis of what is actually different. I can say that this is not true. The 'ipaccess BSC' is a narrow definition and would just include the messages sent by OML to configure the BTS but even in the broader sense of using 'ipaccess' only software it is not true. holger From hwit at a-domani.nl Sat Jan 25 11:01:39 2014 From: hwit at a-domani.nl (Hans Witvliet) Date: Sat, 25 Jan 2014 12:01:39 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140125100031.GD9524@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140124202921.2029.qmail@stuge.se> <20140125100031.GD9524@xiaoyu.lan> Message-ID: <1390647699.28870.2.camel@orion.a-domani.nl> On Sat, 2014-01-25 at 11:00 +0100, Holger Hans Peter Freyther wrote: > On Fri, Jan 24, 2014 at 09:29:21PM +0100, Peter Stuge wrote: > > > nanoBTS is a completely closed source product. Their GPRS stack > > > has reliability issues > > > > Just a note that I've heard that nanoBTS GPRS is perfectly reliable > > with the ipaccess BSC. I haven't seen it myself though. Maybe some > > day there will be some analysis of what is actually different. > > I can say that this is not true. The 'ipaccess BSC' is a narrow > definition and would just include the messages sent by OML to > configure the BTS but even in the broader sense of using 'ipaccess' > only software it is not true. > > holger > So if you are able to "do edge" depends very much on the hardware you've got: http://openbsc.osmocom.org/trac/wiki/nanoBTS/Models And with the 139U you're out of luck, i'll guess... From peter at stuge.se Sat Jan 25 22:26:53 2014 From: peter at stuge.se (Peter Stuge) Date: Sat, 25 Jan 2014 23:26:53 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140125100031.GD9524@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140124202921.2029.qmail@stuge.se> <20140125100031.GD9524@xiaoyu.lan> Message-ID: <20140125222653.18044.qmail@stuge.se> Holger Hans Peter Freyther wrote: > > > nanoBTS is a completely closed source product. Their GPRS stack > > > has reliability issues > > > > Just a note that I've heard that nanoBTS GPRS is perfectly reliable > > with the ipaccess BSC. I haven't seen it myself though. Maybe some > > day there will be some analysis of what is actually different. > > I can say that this is not true. I've seen nanoBTS behaving very inconsistently so I'm not excluding that there are some circumstances in which they actually do work reliably, since I have no reason to doubt what I heard about them working fine together with the ipaccess software. But in any case, a detailed analysis of what is really going would be neccessary in order to potentially make them equally reliable with OpenBSC and I would personally much rather use a sysmoBTS and spend that time on other things. :) //Peter From dchardware at gmail.com Sat Jan 25 11:39:39 2014 From: dchardware at gmail.com (Sipos Csaba) Date: Sat, 25 Jan 2014 12:39:39 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140124122903.GB10034@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: <1845024250.20140125123939@freemail.hu> Thanks again for the infos! Now I have a sense about what unit we should get. So there is only GPRS support at the moment, no EDGE. Do you guys have a plan for EDGE? To be clear I am not demanding anything, just kindly asking :-) Can someone enlighten me about the current limitations of the GPRS stack? For example: what are the slot configuration (or GPRS class) limitations? I am not interested in voice calls so my plan is to configure one (or maybe more than one) TRX with just PDCH channels to gain as much PD bandwidth as much as possible. Can I use more than one downlink or uplink channels if my terminal is capable of doing that? Thanks, Csaba From holger at freyther.de Sat Jan 25 21:47:44 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 25 Jan 2014 22:47:44 +0100 Subject: GPRS, EDGE support In-Reply-To: <1845024250.20140125123939@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <1845024250.20140125123939@freemail.hu> Message-ID: <20140125214744.GL9524@xiaoyu.lan> On Sat, Jan 25, 2014 at 12:39:39PM +0100, Sipos Csaba wrote: Hi again, > So there is only GPRS support at the moment, no EDGE. Do you guys have > a plan for EDGE? To be clear I am not demanding anything, just kindly > asking :-) The answer is complicated. The current PCU code is not really good and we at sysmocom are the only ones changing that. I am keeping a TODO in the osmo-pcu code and post status reports to the PCU mailinglist from time[1] to time. The current agenda is: * Re-factor code so it can be unit-tested and write tests * Optimize bandwidth usage * Dynamic CS mode switch After this we will support EDGE (in a non-mixed mode config). The structure will not change that much when EDGE is added. The window handling is more dynamic (dl/ul size can be dynamically decided), more codec schemes, new CSN1 messages. > Can someone enlighten me about the current limitations of the GPRS > stack? Please have a look here[2]. > > For example: what are the slot configuration (or GPRS class) limitations? I am not > interested in voice calls so my plan is to configure one (or maybe > more than one) TRX with just PDCH channels to gain as much PD > bandwidth as much as possible. > Can I use more than one downlink or uplink channels if my terminal is capable of > doing that? The current allocator can assign multiple downlink slots. It will assign only a single uplink though. The bad part is that the same uplink slot will be assigned for all phones. The more phones you have the more problems you will get. E.g. to ACK the TCP frame all phones compete for the same uplink resource.. while all other PDCHs have no uplink usage... It is just one example of the problem space one has to deal with in GPRS/EDGE PCU. cheers holger [1] http://lists.osmocom.org/pipermail/osmocom-pcu/2014-January/thread.html [2] http://openbsc.osmocom.org/trac/wiki/osmo-pcu#Status From dchardware at gmail.com Sun Jan 26 10:20:25 2014 From: dchardware at gmail.com (Sipos Csaba) Date: Sun, 26 Jan 2014 11:20:25 +0100 Subject: GPRS, EDGE support In-Reply-To: <20140125214744.GL9524@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <1845024250.20140125123939@freemail.hu> <20140125214744.GL9524@xiaoyu.lan> Message-ID: <1677683032.20140126112025@freemail.hu> Hi Holger, > The current allocator can assign multiple downlink slots. It will > assign only a single uplink though. The bad part is that the same > uplink slot will be assigned for all phones. The more phones you > have the more problems you will get. E.g. to ACK the TCP frame all > phones compete for the same uplink resource.. while all other PDCHs > have no uplink usage... Is there a plan to change that one behavior (only one UL slot)? After browsing the code for a few days, it is clear that currently the main stage of development is the PCU and around packet access in general. And I think a lot of people are interested about your work, but except this mailing list, it is really hard to see that, or find infos. This is why I am keep telling you that a blog or a priority list or something on the site would be important to raise awareness. BR, Csaba From holger at freyther.de Sun Jan 26 18:51:00 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 19:51:00 +0100 Subject: GPRS, EDGE support In-Reply-To: <1677683032.20140126112025@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <1845024250.20140125123939@freemail.hu> <20140125214744.GL9524@xiaoyu.lan> <1677683032.20140126112025@freemail.hu> Message-ID: <20140126185100.GB2863@xiaoyu.lan> On Sun, Jan 26, 2014 at 11:20:25AM +0100, Sipos Csaba wrote: > Is there a plan to change that one behavior (only one UL slot)? Sure, but talk is cheap. In general one UL slot is just fine, the main issue is that all phones will compete for the same uplink slot. > After browsing the code for a few days, it is clear that currently the > main stage of development is the PCU and around packet access in > general. And I think a lot of people are interested about your work, > but except this mailing list, it is really hard to see that, or find > infos. This is why I am keep telling you that a blog or a priority > list or something on the site would be important to raise awareness. In terms of the osmo-pcu my primary goal is to add architecture to the code, to be able to write unit tests and improving the general quality (e.g. when Daniel and me did this on the assignment algorithm we found defects, shortcomings, limitations...) and we still need to do this throughout the code. In terms of blogs. What we really need are people that want to do engineering and want to work on some harder problems. In general this can be either through: a.) Student projects that are mentored by sysmocom b.) More purchases of BTS by customers that want GPRS so we can dedicate more resources to the work on the PCU by an engineers. c.) Dedicated projects on GPRS/EDGE to improve it. cheers holger PS: Make sure to look at the sysmocom/master branch of the osmo-pcu From alexander.chemeris at gmail.com Sun Jan 26 20:55:31 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 00:55:31 +0400 Subject: GPRS, EDGE support In-Reply-To: <20140124122903.GB10034@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: Hi Holger, On Fri, Jan 24, 2014 at 4:29 PM, Holger Hans Peter Freyther wrote: > SDRs provide the greatest flexibility but unless you have specific > RF filters in your frontend you will not pass the harmonized norms > of the European Union for GSM. This is a very broad statement. AFAICT, UmTRX passes GSM specs as specified by the 3GPP is calibrated properly. Could you point out which specs you mean and some proof that _no_ SDR device can pass that spec? > The majority of the code of osmo-pcu has been contributed by or on > behalf of sysmocom. If you take a look at the development of the PCU > for the last 6 months you will clearly see that sysmocom is doing all > the work. Just like with OpenBSC a lot of others benefit from our work > though. ;) We all appreciate the effort Sysmocom and you personally has been putting into the development of OsmoPCU for past 6 months and we all love shameless commercials on this mailing list. For the sake of completeness, I want to point out that the code was originally written by Ivan Kluchnikov (Fairwaves employee) under my mentorship. We left it in a stage of the proof of concept, since we have never had any commercial customers for it. Then a few features were added by Andreas Eversberg. And then Sysmocom took a turn to restructure the code and make it closer to production. That's what I like about open-source and cooperation in general - everyone contributes a little bit and a project becomes better than if everyone wrote the thing from scratch. At this moment we (Fairwaves) are busy with fixing bugs and improving the CS part of NITB (calls and SMS), but I hope we'll get back to GPRS as we get more customers demanding it. As usual, one can support this with paid feature requests and with buying more of our hardware. And just by submitting more high-quality patches, i.e. by more cooperation. :) Happy hacking! -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Jan 26 21:13:27 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 26 Jan 2014 22:13:27 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: <20140126211327.GC4274@xiaoyu.lan> On Mon, Jan 27, 2014 at 12:55:31AM +0400, Alexander Chemeris wrote: > At this moment we (Fairwaves) are busy with fixing bugs and improving > the CS part of NITB (calls and SMS), but I hope we'll get back to GPRS > as we get more customers demanding it. As usual, one can support this Ah that is great news. Do you mind sharing with the community which defects you are experiencing? cheers holger From alexander.chemeris at gmail.com Mon Jan 27 08:26:27 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 12:26:27 +0400 Subject: GPRS, EDGE support In-Reply-To: <20140126211327.GC4274@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> Message-ID: Hi Holger, On Mon, Jan 27, 2014 at 1:13 AM, Holger Hans Peter Freyther wrote: > On Mon, Jan 27, 2014 at 12:55:31AM +0400, Alexander Chemeris wrote: > >> At this moment we (Fairwaves) are busy with fixing bugs and improving >> the CS part of NITB (calls and SMS), but I hope we'll get back to GPRS >> as we get more customers demanding it. As usual, one can support this > > Ah that is great news. Do you mind sharing with the community which > defects you are experiencing? Definitely. You've seen some of hose patches at the mailing list. Unfortunately we haven't had enough free time yet to merge them into master, as we've been using jolly-branches. I hope that jolly-branches will be merged into master soon, including the osmo-trx support, and we'll submit those patches for merging to master as well. As an example, we're experiencing issues with SMS delivery in a case of spotty coverage and high network load. It's too early to share anything, as we're still understanding the reasons and how to solve this. We're looking into may be writing a unit test for the NITB's SMSC, but it's not clear yet how to do this cleanly and without too much effort. Another issue with SMS is that validity period is not supported and SMS stay in the DB forever, making to too slow after just a few days of usage. Then, there is an issue with OsmoBTS when there are too many phones are trying to connect to it for LUR. I described this a while ago, but we haven't had time to look more into it yet. So far we just used various workarounds to solve it. We're looking into writing a BS power reduction algorithm, similar to the one used in OpenBTS - If there is a severe congestion for LU's, BS will reduce its power until the load doesn't stabilize. Then it'll slowly increase the power again, until it hits the LU congestion or hits the maximum specified power. Then, there is this whole big thing about using an SQLite DB for everything, from HLR to SMSC to counters storage. This is fine for testing, but has its limitations when you run the system 24/7 under a heavy load. At this moments we're using workarounds like not storing counters in the DB and cleaning up the DB with a script, but we're looking into solving this in a proper way. These all is quite a lot of work, unfortunately, and it distracts us from working more on shiny new features like GPRS and EDGE. PS If there is any interest, I can talk at OsmoDevCon about our experience in running OsmoNITB in production and what we see as the challenges moving forward. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From ralph at schmid.xxx Mon Jan 27 15:07:47 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Mon, 27 Jan 2014 16:07:47 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> Message-ID: <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> Hi, > Then, there is an issue with OsmoBTS when there are too many phones are > trying to connect to it for LUR. I described this a while ago, but we haven't > had time to look more into it yet. So far we just used various workarounds to > solve it. We're looking into writing a BS power reduction algorithm, similar to > the one used in OpenBTS - If there is a severe congestion for LU's, BS will > reduce its power until the load doesn't stabilize. Then it'll slowly increase the > power again, until it hits the LU congestion or hits the maximum specified > power. Sure that this is a good idea? It will throw out all users at the edge of the coverage area, maybe cause even more load, when those show up again with their accumulated requests like call attempts, SMS, additional LU, and in fact I have never seen that commercial networks do something like that. Is there not some waiting queue defined in the standards, with some timers, commanding the location updaters to wait for some period of time? Has been a long time when I looked into this, but I mean to remember that even OpenBTS does it this way. Or am I totally wrong? From alexander.chemeris at gmail.com Mon Jan 27 19:56:34 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 23:56:34 +0400 Subject: GPRS, EDGE support In-Reply-To: <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> Message-ID: Ralph, On Mon, Jan 27, 2014 at 7:07 PM, Ralph A. Schmid, dk5ras wrote: >> Then, there is an issue with OsmoBTS when there are too many phones are >> trying to connect to it for LUR. I described this a while ago, but we haven't >> had time to look more into it yet. So far we just used various workarounds to >> solve it. We're looking into writing a BS power reduction algorithm, similar to >> the one used in OpenBTS - If there is a severe congestion for LU's, BS will >> reduce its power until the load doesn't stabilize. Then it'll slowly increase the >> power again, until it hits the LU congestion or hits the maximum specified >> power. > > Sure that this is a good idea? It will throw out all users at the edge of the coverage > area, maybe cause even more load, when those show up again with their accumulated > requests like call attempts, SMS, additional LU, and in fact I have never seen that > commercial networks do something like that. > > Is there not some waiting queue defined in the standards, with some timers, > commanding the location updaters to wait for some period of time? Has > been a long time when I looked into this, but I mean to remember that even > OpenBTS does it this way. > > Or am I totally wrong? > > From my point of view slowly increasing TX power is OK for booting a new cell into > operation, but during normal operation?! This is for the initial startup of a cell and for a situation of a sudden influx of a huge number of phones. In a normal situation you should not have RACH channel saturated and thus this mechanism is not triggered, -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From ralph at schmid.xxx Tue Jan 28 08:29:36 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 28 Jan 2014 09:29:36 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> Message-ID: <001301cf1c03$149f5660$3dde0320$@schmid.xxx> Hi, > This is for the initial startup of a cell and for a situation of a sudden influx of a > huge number of phones. In a normal situation you should not have RACH > channel saturated and thus this mechanism is not triggered, It is a very common situation that for example a train with a few hundred phones enters the tunnel area what is connected to a different location area, and all those phones want to perform a location update. Happens not far from my home every few minutes, for almost 20 hours per day, for about ten years now :) Btw., OpenBTS seems to handle this quite well, I had the situation of about 60 phone jumping onto my poor little USRP1/WBX cell, and I mean to remember that even the console output showed the queue handling. So I am not sure if such a measure like reducing the power would be useful at all in whatever scenario. Commercial systems that I monitored after breakdowns or maintenance shutdowns just came back again with full power, it all sorted out itself within short time. Among them were cells near airports or heavily crowded roads and pedestrian areas. I wonder if we see a problem where in fact there isn't one at all. > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves LLC / ??? ??????? > http://fairwaves.ru Ralph. From dburgess at jcis.net Tue Jan 28 11:11:58 2014 From: dburgess at jcis.net (David A. Burgess) Date: Tue, 28 Jan 2014 13:11:58 +0200 Subject: GPRS, EDGE support In-Reply-To: <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> Message-ID: <3D7162D8-D262-4843-B52D-6F3186B7611D@jcis.net> Ralph - On Jan 27, 2014, at 17:07, Ralph A. Schmid, dk5ras wrote: > Hi, > >> Then, there is an issue with OsmoBTS when there are too many phones are >> trying to connect to it for LUR. I described this a while ago, but we haven't >> had time to look more into it yet. So far we just used various workarounds to >> solve it. We're looking into writing a BS power reduction algorithm, similar to >> the one used in OpenBTS - If there is a severe congestion for LU's, BS will >> reduce its power until the load doesn't stabilize. Then it'll slowly increase the >> power again, until it hits the LU congestion or hits the maximum specified >> power. > > Sure that this is a good idea? It will throw out all users at the edge of the coverage > area, maybe cause even more load, when those show up again with their accumulated > requests like call attempts, SMS, additional LU, and in fact I have never seen that > commercial networks do something like that. > > Is there not some waiting queue defined in the standards, with some timers, > commanding the location updaters to wait for some period of time? Has > been a long time when I looked into this, but I mean to remember that even > OpenBTS does it this way. There is a hold-off timer sent in the immediate assignment reject message, but it is still possible for the RACH to be so congested that only a small fraction of bursts are decodable. And it is possible for the AGCH to be so congested that it is impossible to respond to any significant fraction of the requests anyway. Once this happens, you get a kind of live-lock on the air interface. If you are the only BTS in the area, this locked condition can persist for hours. You can either turn down the power and reduce the number of phones in the coverage area and serve that reduced population, or stay in the live-lock condition and not serve anyone. Yes, you ramp up power on startup. We just automated that process. And unless the BTS falls into this kind of live-lock condition, because of the sudden failure of a neighbor cell or some other overlapping network, this mechanism does not take any action. > > Or am I totally wrong? > >> From my point of view slowly increasing TX power is OK for booting a new cell into > operation, but during normal operation?! It?s not normal operation. It is an emergency measure that takes effect with the network is in a hopeless congestion condition. And in my experience, this approach changes the recovery time from several hours to several minutes. > >> -- >> Regards, >> Alexander Chemeris. >> CEO, Fairwaves LLC / ??? ??????? >> http://fairwaves.ru > > Ralph. > > From ralph at schmid.xxx Tue Jan 28 11:29:38 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 28 Jan 2014 12:29:38 +0100 Subject: GPRS, EDGE support In-Reply-To: <3D7162D8-D262-4843-B52D-6F3186B7611D@jcis.net> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> <3D7162D8-D262-4843-B52D-6F3186B7611D@jcis.net> Message-ID: <002901cf1c1c$3aa1ad90$afe508b0$@schmid.xxx> > It?s not normal operation. It is an emergency measure that takes effect with > the network is in a hopeless congestion condition. And in my experience, > this approach changes the recovery time from several hours to several > minutes. About what numbers of phones are we talking here to reach a critical mass? Usually a phone transmits two or three access bursts, then it waits for a while, and I mean to remember some slotted aloha scheme, or similar. I hardly can imagine that such a condition could last for_hours_, but of course the real word sometimes offers bad surprises :) Ralph. From dburgess at jcis.net Tue Jan 28 15:30:35 2014 From: dburgess at jcis.net (David A. Burgess) Date: Tue, 28 Jan 2014 17:30:35 +0200 Subject: GPRS, EDGE support In-Reply-To: <002901cf1c1c$3aa1ad90$afe508b0$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140126211327.GC4274@xiaoyu.lan> <00cd01cf1b71$8a2b4660$9e81d320$@schmid.xxx> <3D7162D8-D262-4843-B52D-6F3186B7611D@jcis.net> <002901cf1c1c$3aa1ad90$afe508b0$@schmid.xxx> Message-ID: <70E7CD7C-9C6C-4469-8336-28A65B347717@jcis.net> You start seeing this with several thousand phones. On Jan 28, 2014, at 13:29, Ralph A. Schmid, dk5ras wrote: >> It?s not normal operation. It is an emergency measure that takes effect with >> the network is in a hopeless congestion condition. And in my experience, >> this approach changes the recovery time from several hours to several >> minutes. > > About what numbers of phones are we talking here to reach a critical mass? > Usually a phone transmits two or three access bursts, then it waits for a while, > and I mean to remember some slotted aloha scheme, or similar. I hardly can > imagine that such a condition could last for_hours_, but of course the real > word sometimes offers bad surprises :) > > Ralph. > > > From tom at tsou.cc Sun Jan 26 23:29:00 2014 From: tom at tsou.cc (Tom Tsou) Date: Sun, 26 Jan 2014 18:29:00 -0500 Subject: GPRS, EDGE support In-Reply-To: <20140124122903.GB10034@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: On Fri, Jan 24, 2014 at 7:29 AM, Holger Hans Peter Freyther wrote: > SDRs provide the greatest flexibility but unless you have specific > RF filters in your frontend you will not pass the harmonized norms > of the European Union for GSM. I think this statement is quite dated. A calibrated USRP N200 running osmo-trx passes RF spectrum and modulation accuracy requirements of 3GPP 05.05 by very large margins and is competitive with commercial GSM equipment in this regard. Other SDR devices are also capable to varying degrees. -TT From holger at freyther.de Mon Jan 27 12:49:43 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 27 Jan 2014 13:49:43 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> Message-ID: <20140127124943.GC32756@xiaoyu.lan> On Sun, Jan 26, 2014 at 06:29:00PM -0500, Tom Tsou wrote: > On Fri, Jan 24, 2014 at 7:29 AM, Holger Hans Peter Freyther > wrote: > > SDRs provide the greatest flexibility but unless you have specific > > RF filters in your frontend you will not pass the harmonized norms > > of the European Union for GSM. > > I think this statement is quite dated. Ah cool. Can you point me to papers/text showing how the n-th harmonic is being removed from the spectrum? > A calibrated USRP N200 running osmo-trx passes RF spectrum and > modulation accuracy requirements of 3GPP 05.05 by very large margins > and is competitive with commercial GSM equipment in this regard. Other > SDR devices are also capable to varying degrees. The policy of FCC vs. European Union is quite different. There are more norms that apply in Europe. From tom at tsou.cc Mon Jan 27 19:48:40 2014 From: tom at tsou.cc (Tom Tsou) Date: Mon, 27 Jan 2014 14:48:40 -0500 Subject: GPRS, EDGE support In-Reply-To: <20140127124943.GC32756@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> Message-ID: On Mon, Jan 27, 2014 at 7:49 AM, Holger Hans Peter Freyther wrote: > On Sun, Jan 26, 2014 at 06:29:00PM -0500, Tom Tsou wrote: >> On Fri, Jan 24, 2014 at 7:29 AM, Holger Hans Peter Freyther >> wrote: >> > SDRs provide the greatest flexibility but unless you have specific >> > RF filters in your frontend you will not pass the harmonized norms >> > of the European Union for GSM. >> >> I think this statement is quite dated. > > Ah cool. Can you point me to papers/text showing how the n-th harmonic > is being removed from the spectrum? N-th harmonic of what? For the N200, The GSM baseband signal goes through a number of conversions and filtering stages on the host, FPGA, and DAC chip before reaching the converter at an interpolated rate of 400 Msps. There is 40 MHz of filtering on the WBX daughterboard, which removes aliasing from the DAC output. The older RFX900 daughterboard does have a filter on the front end, however, the performance is worse than the WBX in almost every measure. More recent devices are based on flexible integrated RF chips from Analog Devices and Lime Micro that were specifically designed for commercial 3G and 4G systems. I find it hard to believe that these SDR products are not capable of passing international compliance requirements for GSM. > The policy of FCC vs. European Union is quite different. There are more > norms that apply in Europe. Certain USRP products, notably the National Instruments variants, are CE tested and certified according to applicable European directives for which the product is sold. I am certainly not an expert in the area of compliance, but I assume this certification does not extend to operation of a GSM base station as the product is not sold as such. That brings up the point that for USRP type devices, the user is purchasing a piece of test equipment and not a BTS and is therefore responsible for meeting any subsequent application requirements. This contrasts with nanoBTS or sysmoBTS, which are fixed use GSM products and the burden of compliance lies with the supplier. For users who are concerned about compliance, the classification of the device is probably a larger issue than whether or not the device is technically capable of passing compliance norms. -TT From ralph at schmid.xxx Tue Jan 28 08:49:16 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Tue, 28 Jan 2014 09:49:16 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> Message-ID: <001501cf1c05$d3be1de0$7b3a59a0$@schmid.xxx> Hi, > > Ah cool. Can you point me to papers/text showing how the n-th harmonic > > is being removed from the spectrum? > > N-th harmonic of what? Of the RF carrier. I guess there will be some harmonics, and I will have a look what my WBX produces if you are interested. > More recent devices are based on flexible integrated RF chips from Analog > Devices and Lime Micro that were specifically designed for commercial 3G > and 4G systems. I find it hard to believe that these SDR products are not > capable of passing international compliance requirements for GSM. Usually there is even for those low power applications some passband filter in the output path. Ralph. From tom at tsou.cc Tue Jan 28 16:10:15 2014 From: tom at tsou.cc (Tom Tsou) Date: Tue, 28 Jan 2014 11:10:15 -0500 Subject: GPRS, EDGE support In-Reply-To: <001501cf1c05$d3be1de0$7b3a59a0$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> <001501cf1c05$d3be1de0$7b3a59a0$@schmid.xxx> Message-ID: On Tue, Jan 28, 2014 at 3:49 AM, Ralph A. Schmid, dk5ras wrote: >> N-th harmonic of what? > > Of the RF carrier. I guess there will be some harmonics, and I will have a > look > what my WBX produces if you are interested. Note that the USRP1-WBX combination does not support LO offset or IQ imbalance compensation; those factors will be your largest source of overall signal distortion. In regards to the harmonic distortion, it seems that the concern is over spurious free dynamic range (SFDR) of front end components, which is more of an issue of wideband RF design than SDR in general. Similar issues can exist in any wireless system - SDR or not. >> More recent devices are based on flexible integrated RF chips from Analog >> Devices and Lime Micro that were specifically designed for commercial 3G >> and 4G systems. I find it hard to believe that these SDR products are not >> capable of passing international compliance requirements for GSM. > > Usually there is even for those low power applications some passband filter > in the output path. I will certainly not deny that spurious signals exist in USRP-type boards or that passband filters are used in commercial products. My only issue is the claim that a narrow tuning range limited by front end filters is a mandatory requirement for suitable spectrum compliance. A huge number of frequency bands is required by current and future wireless services and attaching a fixed RF filter for every individual band in use is not a sustainable approach. There has been a very significant amount of development in flexible RF design over the past decade in order to address these issues, which I do not think should be ignored. -TT From ralph at schmid.xxx Wed Jan 29 07:23:27 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Wed, 29 Jan 2014 08:23:27 +0100 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> <001501cf1c05$d3be1de0$7b3a59a0$@schmid.xxx> Message-ID: <001e01cf1cc3$011186c0$03349440$@schmid.xxx> Hi, > Note that the USRP1-WBX combination does not support LO offset or IQ > imbalance compensation; those factors will be your largest source of overall > signal distortion. In regards to the harmonic distortion, it seems that the > concern is over spurious free dynamic range (SFDR) of front end > components, which is more of an issue of wideband RF design than SDR in > general. Similar issues can exist in any wireless system - SDR or not. Yes, sure, this is normal behavior. > I will certainly not deny that spurious signals exist in USRP-type boards or that > passband filters are used in commercial products. My only issue is the claim > that a narrow tuning range limited by front end filters is a mandatory > requirement for suitable spectrum compliance. A huge number of frequency I see more problems in the receiver stages, and there parameters are also mandatory during compliance tests. > bands is required by current and future wireless services and attaching a > fixed RF filter for every individual band in use is not a sustainable approach. > There has been a very significant amount of development in flexible RF > design over the past decade in order to address these issues, which I do not > think should be ignored. Of course, this is true, but do not forget the strong signals that come backwards, from other transmitters at a populated antenna site. Those can do nasty things in the PAs, so some filters and isolators can hardly be eliminated. A high power wideband system out in the wild is another beast than hooked to your lab setup. > -TT Ralph. From tom at tsou.cc Wed Jan 29 08:20:56 2014 From: tom at tsou.cc (Tom Tsou) Date: Wed, 29 Jan 2014 03:20:56 -0500 Subject: GPRS, EDGE support In-Reply-To: <001e01cf1cc3$011186c0$03349440$@schmid.xxx> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> <001501cf1c05$d3be1de0$7b3a59a0$@schmid.xxx> <001e01cf1cc3$011186c0$03349440$@schmid.xxx> Message-ID: On Wed, Jan 29, 2014 at 2:23 AM, Ralph A. Schmid, dk5ras wrote: > Of course, this is true, but do not forget the strong signals that come > backwards, from > other transmitters at a populated antenna site. Those can do nasty things in > the PAs, > so some filters and isolators can hardly be eliminated. A high power > wideband system > out in the wild is another beast than hooked to your lab setup. I don't think myself or anyone else was ever implying that *all* front end filtering should be eliminated. Surely, if one is operating a high power transmitter at a populated side, then appropriate precautions would be in order. We've drifted very far off-topic at this point. I have nothing else to add. -TT From alexander.chemeris at gmail.com Tue Jan 28 18:12:37 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 28 Jan 2014 22:12:37 +0400 Subject: GPRS, EDGE support In-Reply-To: <20140127124943.GC32756@xiaoyu.lan> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> <20140124122903.GB10034@xiaoyu.lan> <20140127124943.GC32756@xiaoyu.lan> Message-ID: Hi Holger, On Mon, Jan 27, 2014 at 4:49 PM, Holger Hans Peter Freyther wrote: > On Sun, Jan 26, 2014 at 06:29:00PM -0500, Tom Tsou wrote: >> On Fri, Jan 24, 2014 at 7:29 AM, Holger Hans Peter Freyther >> wrote: >> > SDRs provide the greatest flexibility but unless you have specific >> > RF filters in your frontend you will not pass the harmonized norms >> > of the European Union for GSM. >> >> I think this statement is quite dated. > > Ah cool. Can you point me to papers/text showing how the n-th harmonic > is being removed from the spectrum? Do you mean carrier harmonics? From alexander.chemeris at gmail.com Fri Jan 24 14:52:33 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 24 Jan 2014 18:52:33 +0400 Subject: GPRS, EDGE support In-Reply-To: <1023409662.20140124105951@freemail.hu> References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> Message-ID: Hi Sipos, On Fri, Jan 24, 2014 at 1:59 PM, Sipos Csaba wrote: > For GPRS/EDGE to work I need to choose from the following HW: > > - USRP2 (I also heard that USRP1 has timing problems, but as I know, > these problems are fixed in USRP2 and the networked series?) > - UmTRX > - BladeRF (according to them, they are quite close to running OpenBTS) > - SysmoBTS > - NanoBTS > > Correct? In general, my personal comparison is like that (in random order, not in the order of preference): - Get USRP N (not USRP 2), if you want to have access to variety of daughter boards, available for USRPs. Though it's quite expensive, especially if you add a GPSDO to it. - Get UmTRX if you want a device which is smaller and cheaper than USRP N and with 2 channels and embedded GPS. Though you'll need to take care of enclosure by yourself. - You can also get UmTRAY or UmDESK, but they are more expensive. - Get USRP B200, if you want a small single-channel device. Though you _may_ have issue if you start playing with handover, as it doesn't have GPS or a stable enough reference clock. - Get BladeRF if you like debugging. :) Though you _may_ have issue if you start playing with handover, as it doesn't have GPS or a stable enough reference clock. - Get SysmoBTS if you want an all-in-one device which you could run without a laptop. Though it's single-channel can't support multi-ARFCN. Also be prepared that it has ARM inside, which adds some fun to the development process. - NanoBTS? Why would you ever want that? > I am more convinced to buy an SDR like device, because we can use that > for other stuff too. But if you are telling me, that for example > SysmoBTS or NanoBTS runs the GRPS stack better, compared to UmTRX or > USRP2, than I can respect that. In terms of GPRS all these devices have the same capabilities, since they share the same PCU/SGSN/GGSN code. EDGE is not supported by PCU and thus can't work on any of these devices. SysmoBTS and NanoBTS has lower levels of EDGE implemented, since they use some proprietary code or that, so they are little bit closer to having EDGE. All of the other devices are fully capable of EDGE in terms of hardware, but there is no software support for that. > I also want to ask one more time, if it is possible to run multiple > TRXes on one SDR like device which has enough processing power and > bandwidth? Did someone already tried this? Or it is not even possible? UmTRX has two independent TRXs and we use it in dual-TRX mode in all our installations. All of the SDR devices mentioned above are technically capable of running in the Multi-ARFCN mode. OsmoTRX has support for that, but no one has tested it with OsmoBTS/OsmoNITB yet. IIRC, SysmoBTS is single channel only. Holger could correct me if I'm wrong. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From matt at ettus.com Fri Jan 24 17:15:43 2014 From: matt at ettus.com (Matt Ettus) Date: Fri, 24 Jan 2014 09:15:43 -0800 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> Message-ID: I normally resist talking about our own products on this list, but since there is some incomplete information I will offer some corrections. I won't speak to competitor's products. > - Get USRP N (not USRP 2), if you want to have access to variety of > daughter boards, available for USRPs. Though it's quite expensive, > especially if you add a GPSDO to it. > These are the highest dynamic range and will have the best RF performance. > - Get USRP B200, if you want a small single-channel device. Though > you _may_ have issue if you start playing with handover, as it doesn't > have GPS or a stable enough reference clock. > A GPSDO is available for B200, or you can use the 10 MHz input from an external source. The B200 is by far the lowest cost option, and it has a high dynamic range in comparison to Lime-based solutions. If you want diversity receive and dual transmit, you can get the B210 which is also a low cost option. Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Sun Jan 26 20:35:19 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 00:35:19 +0400 Subject: GPRS, EDGE support In-Reply-To: References: <1529289201.20140123123355@freemail.hu> <20140124083257.GC4910@xiaoyu.lan> <1023409662.20140124105951@freemail.hu> Message-ID: Matt, On Fri, Jan 24, 2014 at 9:15 PM, Matt Ettus wrote: > I normally resist talking about our own products on this list, but since > there is some incomplete information I will offer some corrections. I won't > speak to competitor's products. Thank you for more details, this is appreciated. >> - Get USRP N (not USRP 2), if you want to have access to variety of >> daughter boards, available for USRPs. Though it's quite expensive, >> especially if you add a GPSDO to it. > > These are the highest dynamic range and will have the best RF performance. > >> - Get USRP B200, if you want a small single-channel device. Though >> you _may_ have issue if you start playing with handover, as it doesn't >> have GPS or a stable enough reference clock. > > A GPSDO is available for B200, or you can use the 10 MHz input from an > external source. The B200 is by far the lowest cost option, and it has a > high dynamic range in comparison to Lime-based solutions. If you want > diversity receive and dual transmit, you can get the B210 which is also a > low cost option. This is all correct. I just want to point that dual-channel with B210 is not (yet) supported by osmo-trx, so one will need a little bit of effort to run it in dual-TRX mode. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Fri Jan 24 12:48:19 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 24 Jan 2014 13:48:19 +0100 Subject: [PATCH] lapd/test: Add test case for RSL EST REQ -> LAPD Message-ID: <1390567699-21971-1-git-send-email-jerlbeck@sysmocom.de> This test case processes RSL establish requests for SMS (SAPI 3) on the SDCCH and the SACCH channels. The TX queues are checked after processing each message. Ticket: #225 Sponsored-by: On-Waves ehf --- tests/lapd/lapd_test.c | 120 +++++++++++++++++++++++++++++++++++++++++------ tests/lapd/lapd_test.ok | 7 +++ 2 files changed, 112 insertions(+), 15 deletions(-) diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index 37c0db8..b4594de 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -80,6 +80,14 @@ static const uint8_t rel_req[] = { 0x02, 0x07, 0x01, 0x0a, 0x02, 0x40, 0x14, 0x01 }; +static const uint8_t est_req_sdcch_sapi3[] = { + 0x02, 0x04, 0x01, 0x20, 0x02, 0x03 +}; + +static const uint8_t est_req_sacch_sapi3[] = { + 0x02, 0x04, 0x01, 0x0b, 0x02, 0x43 +}; + static struct msgb *create_cm_serv_req(void) { struct msgb *msg; @@ -131,6 +139,16 @@ static struct msgb *create_rel_req(void) return msg; } +static struct msgb *create_est_req(const uint8_t *est_req, size_t est_req_size) +{ + struct msgb *msg; + + msg = msgb_from_array(est_req, est_req_size); + msg->l2h = msg->data; + msg->l3h = msg->l2h + sizeof(struct abis_rsl_rll_hdr); + return msg; +} + static int send(struct msgb *in_msg, struct lapdm_channel *chan) { struct osmo_phsap_prim pp; @@ -350,6 +368,52 @@ static void test_lapdm_polling() lapdm_channel_exit(&ms_to_bts_channel); } +static void test_lapdm_contention_resolution() +{ + printf("I test contention resultion by having two mobiles collide and " + "first mobile repeating SABM.\n"); + + int rc; + struct lapdm_polling_state test_state; + struct osmo_phsap_prim pp; + + /* Configure LAPDm on both sides */ + struct lapdm_channel bts_to_ms_channel; + memset(&bts_to_ms_channel, 0, sizeof(bts_to_ms_channel)); + + memset(&test_state, 0, sizeof(test_state)); + test_state.bts = &bts_to_ms_channel; + + /* BTS to MS in polling mode */ + lapdm_channel_init(&bts_to_ms_channel, LAPDM_MODE_BTS); + lapdm_channel_set_flags(&bts_to_ms_channel, LAPDM_ENT_F_POLLING_ONLY); + lapdm_channel_set_l1(&bts_to_ms_channel, NULL, &test_state); + lapdm_channel_set_l3(&bts_to_ms_channel, bts_to_ms_tx_cb, &test_state); + + /* 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); + 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); + 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); + CHECK_RC(rc); + OSMO_ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); + + /* clean up */ + lapdm_channel_exit(&bts_to_ms_channel); + + /* idempotent */ + lapdm_channel_exit(&bts_to_ms_channel); +} + static void test_lapdm_early_release() { printf("I test RF channel release of an unestablished channel.\n"); @@ -381,14 +445,13 @@ static void test_lapdm_early_release() lapdm_channel_exit(&bts_to_ms_channel); } -static void test_lapdm_contention_resolution() +static void lapdm_establish(const uint8_t *est_req, size_t est_req_size) { - printf("I test contention resultion by having two mobiles collide and " - "first mobile repeating SABM.\n"); - int rc; 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; @@ -403,22 +466,39 @@ static void test_lapdm_contention_resolution() lapdm_channel_set_l1(&bts_to_ms_channel, NULL, &test_state); lapdm_channel_set_l3(&bts_to_ms_channel, bts_to_ms_tx_cb, &test_state); - /* Send SABM MS 1, we must get UA */ - send_sabm(&bts_to_ms_channel, 0); + /* Send the release request */ + msg = create_est_req(est_req, est_req_size); + rc = lapdm_rslms_recvmsg(msg, &bts_to_ms_channel); + fprintf(stderr, "recvmsg: got rc %d: %s\n", rc, rc <= 0 ? strerror(-rc) : "???"); + 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"; + } + + fprintf(stderr, "dequeue: got rc %d: %s\n", rc, + rc <= 0 ? strerror(-rc) : "-"); 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); - OSMO_ASSERT(rc == -ENODEV); + 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)); - /* 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); - CHECK_RC(rc); - OSMO_ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); + OSMO_ASSERT(rc < 0); + rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_acch, &pp); + OSMO_ASSERT(rc < 0); /* clean up */ lapdm_channel_exit(&bts_to_ms_channel); @@ -427,6 +507,15 @@ static void test_lapdm_contention_resolution() lapdm_channel_exit(&bts_to_ms_channel); } +static void test_lapdm_establishment() +{ + printf("I test RF channel establishment.\n"); + printf("Testing SAPI3/SDCCH\n"); + lapdm_establish(est_req_sdcch_sapi3, sizeof(est_req_sdcch_sapi3)); + printf("Testing SAPI3/SACCH\n"); + lapdm_establish(est_req_sacch_sapi3, sizeof(est_req_sacch_sapi3)); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -434,6 +523,7 @@ int main(int argc, char **argv) test_lapdm_polling(); 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 27389bf..e4b1359 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -21,4 +21,11 @@ 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. +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 +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 Success. -- 1.7.9.5 From andrew at carrierdetect.com Fri Jan 24 15:43:08 2014 From: andrew at carrierdetect.com (Andrew Back) Date: Fri, 24 Jan 2014 15:43:08 +0000 Subject: OsmoBTS branch for network_from_scratch. Message-ID: Hello, When following the network_from_scratch instructions with a Linaro Ubuntu 12.11 host, I encountered a build error when it came to OsmoBTS: linaro-ubuntu-desktop:~/osmocom/osmo-bts> make Making all in include make[1]: Entering directory `/home/linaro/osmocom/osmo-bts/include' Making all in osmo-bts make[2]: Entering directory `/home/linaro/osmocom/osmo-bts/include/osmo-bts' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/home/linaro/osmocom/osmo-bts/include/osmo-bts' make[2]: Entering directory `/home/linaro/osmocom/osmo-bts/include' make[2]: Nothing to be done for `all-am'. make[2]: Leaving directory `/home/linaro/osmocom/osmo-bts/include' make[1]: Leaving directory `/home/linaro/osmocom/osmo-bts/include' Making all in src make[1]: Entering directory `/home/linaro/osmocom/osmo-bts/src' Making all in common make[2]: Entering directory `/home/linaro/osmocom/osmo-bts/src/common' CC gsm_data_shared.o CC sysinfo.o CC logging.o CC abis.o abis.c: In function ?abis_sock_cb?: abis.c:360:2: warning: #warning HACK [-Wcpp] CC oml.o oml.c: In function ?rx_oml_ipa_rsl_connect?: oml.c:1049:17: warning: assignment from incompatible pointer type [enabled by default] oml.c:1053:2: warning: passing argument 1 of ?abis_open? from incompatible pointer type [enabled by default] ../../include/osmo-bts/abis.h:35:5: note: expected ?struct ipabis_link *? but argument is of type ?struct e1inp_sign_link *? CC bts.o CC rsl.o rsl.c:140:2: warning: #warning merge lchan_lookup with OpenBSC [-Wcpp] rsl.c: In function ?get_rsl_local_ip?: rsl.c:1265:32: error: ?struct e1inp_sign_link? has no member named ?bfd? rsl.c: In function ?rsl_rx_ipac_XXcx?: rsl.c:1398:5: warning: initialization from incompatible pointer type [enabled by default] make[2]: *** [rsl.o] Error 1 make[2]: Leaving directory `/home/linaro/osmocom/osmo-bts/src/common' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/linaro/osmocom/osmo-bts/src' make: *** [all-recursive] Error 1 linaro-ubuntu-desktop:~/osmocom/osmo-bts> This was resolved by building from branch jolly/trx_rebased instead of jolly/trx. Should we now be using the rebased branch? If so I will update the wiki. Regards, Andrew -- Andrew Back http://carrierdetect.com From andreas at eversberg.eu Sat Jan 25 05:06:58 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 25 Jan 2014 06:06:58 +0100 Subject: OsmoBTS branch for network_from_scratch. In-Reply-To: References: Message-ID: <52E34672.3070409@eversberg.eu> Andrew Back wrote: hi andrew, > This was resolved by building from branch jolly/trx_rebased instead of > jolly/trx. Should we now be using the rebased branch? If so I will > update the wiki. i have pushed all commits of jolly/trx_rebased to jolly/trx branch. jolly/trx_rebased is now obsolete and so i removed it. in order to make the current jolly/trx branch compile, a special patch for libosmo-abis is required. i pushed the patch to jolly/multi-trx branch of libosmo-abis. check it out and install it first. i have update the network_from_scratch wiki page. if i didn't make a mistake, jolly/trx branch should compile now. thanks for pointing out this problem. best regards, andreas From alexander.chemeris at gmail.com Sat Jan 25 07:54:03 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 25 Jan 2014 11:54:03 +0400 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> Message-ID: Hi Thomas, I'm moving this discussion to the OpenBSC mailing list, as it has nothing to do with UmTRX, but rather with OsmoTRX. On Sat, Jan 25, 2014 at 11:36 AM, Tom Tsou wrote: > On Sat, Jan 25, 2014 at 1:22 AM, Andreas Eversberg wrote: >> once a channel was activeated, >> there will be RF power on the specific TS, even when osmo-bts does not send >> bursts anymore. i guess that some filler table of osmo-trx causes it. i >> think it would be nice if osmo-trx would stop transmitting, when there are >> no more bursts comming from osmo-bts. (at least after a while.) > > Yes, this is the behaviour of the filler table, which will resend the > previous frame until a new frame arrives. Sending an idle frame will > disable output, which is how the filler table is managed in OpenBTS. > You can disable the filler table with this patch. Could you make this configurable from the command line or from the socket control interface? I believe we should leave filler table as the default option, but allow one to disable it when OsmoTRX is used with OsmoBTS. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From andreas at eversberg.eu Sat Jan 25 08:08:45 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 25 Jan 2014 09:08:45 +0100 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> Message-ID: <52E3710D.9070505@eversberg.eu> Alexander Chemeris wrote: >> Yes, this is the behaviour of the filler table, which will resend the >> >previous frame until a new frame arrives. Sending an idle frame will >> >disable output, which is how the filler table is managed in OpenBTS. >> >You can disable the filler table with this patch. > Could you make this configurable from the command line or from the > socket control interface? > > I believe we should leave filler table as the default option, but > allow one to disable it when OsmoTRX is used with OsmoBTS. hi alexander, i think that it does not make sense to add a special option for osmo-bts. better would be to make osmo-bts behave correctly, i.e. similar to OpenBTS. currently osmobts-trx does not send a burst (TRX > 0), if the channel to which it belongs is deactivated. the question to thomas was: how do i send an idle frame, so the filler table gets cleared. best regards, andreas From alexander.chemeris at gmail.com Sat Jan 25 08:26:11 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 25 Jan 2014 12:26:11 +0400 Subject: RF power problems with current master of osmo-trx In-Reply-To: <52E3710D.9070505@eversberg.eu> References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E3710D.9070505@eversberg.eu> Message-ID: Hi Andreas, On Sat, Jan 25, 2014 at 12:08 PM, Andreas Eversberg wrote: > Alexander Chemeris wrote: >>> >>> Yes, this is the behaviour of the filler table, which will resend the >>> >previous frame until a new frame arrives. Sending an idle frame will >>> >disable output, which is how the filler table is managed in OpenBTS. >>> >You can disable the filler table with this patch. >> >> Could you make this configurable from the command line or from the >> socket control interface? >> >> I believe we should leave filler table as the default option, but >> allow one to disable it when OsmoTRX is used with OsmoBTS. > > hi alexander, > > i think that it does not make sense to add a special option for osmo-bts. > better would be to make osmo-bts behave correctly, i.e. similar to OpenBTS. > currently osmobts-trx does not send a burst (TRX > 0), if the channel to > which it belongs is deactivated. > > the question to thomas was: how do i send an idle frame, so the filler table > gets cleared. I can't comment on what is an idle burst, but I want to clarify that I think that the filler table should be turned off. We had this discussion at the 30c3 and the conclusion was that the filler table should be turned off. 1. IIRC from the talk David Burgess did at OsmoDevCon two years ago, the filler table was introduced in OpenBTS as an optimization to reduce load. But nowadays I don't see that running OsmoBTS generates much load. 2. In a normal cell most channels are encrypted, which means that repeating bursts makes no sense for those channels. 3. Repeating bursts on non-encrypted channels can lead to messed L2 connection setup and to dropped calls. It's better to completely miss a burst which will be re-transmitted again after some time, than have a burst transmitted twice. Missing a burst is a normal situation in an air interface and happens all the time. 4. The only channels which benefit from the filler table are BCCH and FCCH. But then we have another issue. If a BTS dies, BCCH and FCCH continues to be transmitted and phones think that the cell is still here. But it reality it's dead. This is quite not handy both for development and for production. Note, that the BTS may die for a variety of reasons and not only because there is some bug in it, and RF transmission must stop at this point. Given these considerations, I believe that we should make the filler table configurable. It is required for OpenBTS and is a nice thing for some lab tests, but for OsmoBTS it's a harmful thing. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From ralph at schmid.xxx Sat Jan 25 09:55:24 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Sat, 25 Jan 2014 10:55:24 +0100 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E3710D.9070505@eversberg.eu> Message-ID: <000301cf19b3$94200300$bc600900$@schmid.xxx> Hi, > 4. The only channels which benefit from the filler table are BCCH and FCCH. But then we have another issue. If a BTS dies, BCCH and FCCH > continues to be transmitted and phones think that the cell is still here. But it reality it's dead. This is quite not handy both for development > and for production. Note, that the BTS may die for a variety of reasons and not only because there is some bug in it, and RF transmission > must stop at this point. Definitely, this even can be a demand from regulation authority, depending on license conditions. This behavior may affect emergency call handling, and the least thing I want to see is interfering with 112/911! Besides, as a ham radio operator I simply consider it good practice taking a transmitter off-air when something dies. Even an unmodulated carrier can be accepted in this case, but not transmitting a BCCH without any meaning. > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves LLC / ??? ??????? > http://fairwaves.ru Ralph, dk5ras :-) -- Ralph A. Schmid Mondstr. 10 90762 F?rth +49-171-3631223 ralph at schmid.xxx http://www.bclog.de/ From tom at tsou.cc Sat Jan 25 18:58:06 2014 From: tom at tsou.cc (Tom Tsou) Date: Sat, 25 Jan 2014 13:58:06 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: <52E36E69.8090704@eversberg.eu> References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> Message-ID: On Sat, Jan 25, 2014 at 2:57 AM, Andreas Eversberg wrote: > so when i stop sending the bursts, the filler table will continue to > transmit bursts. do i understand it correctly: if i send a single idle burst > (frame??) after sending bursts, the filler table is disabled until new > bursts are sent? Sorry, I misspoke about disabling transmission. The filler table resends the last burst in the multiframe, so the idle burst is usually just a dummy burst, which does not actually stop physical transmission. To fully turn off the downlink signal on a particular slot requires disabling the slot by the channel combination. That said, I agree with Alexander that the retransmission portion of the filler table should be turned off because the behavior is incorrect. With a few exceptions (e.g. FCCH), bursts should *not* be retransmitted at L1 and doing so generates an invalid signal. Note that the filler table cannot be completely disabled because it is part of the real-time loop that drives the device I/O. If the upper layer does not send a burst for a particular slot, or that burst arrives late (stale burst), something still must be transmitted. Currently, in that case, the burst comes from the filler table if the slot is active or zeros if the slot is turned off. Again, I do not think the current implementation is entirely correct, but that depends on expectations of the upper layers. -TT From andreas at eversberg.eu Sun Jan 26 14:32:17 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sun, 26 Jan 2014 15:32:17 +0100 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> Message-ID: <52E51C71.1030805@eversberg.eu> Tom Tsou wrote: > That said, I agree with Alexander that the retransmission portion of > the filler table should be turned off because the behavior is > incorrect. hi thomas, this makes sense. repeating any LAPDm frame is definitely something that might cause problems (SDCCH/FACCH/SACCH). even repeating (interleaved) TCH bursts in a multiframe does not make much sense in my opinion. i have just tried your patch. i still get RF power on second TRX. osmobts-trx configures all 8 channels (SETSLOT to TCH/F), but does not send any burst data (TRX 1) to osmo-trx. best regards, andreas From tom at tsou.cc Sun Jan 26 16:35:35 2014 From: tom at tsou.cc (Tom Tsou) Date: Sun, 26 Jan 2014 11:35:35 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: <52E51C71.1030805@eversberg.eu> References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: On Sun, Jan 26, 2014 at 9:32 AM, Andreas Eversberg wrote: > i have just tried your patch. i still get RF power on second TRX. > osmobts-trx configures all 8 channels (SETSLOT to TCH/F), but does not send > any burst data (TRX 1) to osmo-trx. Yes, that is expected behavior. There will be power output as long as the slot is enabled. Right now the only way to turn off transmission is to disable the slot. -TT From alexander.chemeris at gmail.com Sun Jan 26 21:12:45 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 01:12:45 +0400 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: Hi Thomas, On Sun, Jan 26, 2014 at 8:35 PM, Tom Tsou wrote: > On Sun, Jan 26, 2014 at 9:32 AM, Andreas Eversberg wrote: >> i have just tried your patch. i still get RF power on second TRX. >> osmobts-trx configures all 8 channels (SETSLOT to TCH/F), but does not send >> any burst data (TRX 1) to osmo-trx. > > Yes, that is expected behavior. There will be power output as long as > the slot is enabled. Right now the only way to turn off transmission > is to disable the slot. This is an incorrect behavior for TRX1, unlike TRX0. For TRX1 there are no idle bursts and there should be no transmission if there is no data sent. I can't check this right now, but I'm pretty sure that at least some time ago osmo-trx respected this behavior and didn't transmit on TRX1 until it gets something to transmit. I would appreciate if you confirm that the current code still respects this and if you make filler table optional for TRX0 as well. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From tom at tsou.cc Mon Jan 27 01:52:02 2014 From: tom at tsou.cc (Tom Tsou) Date: Sun, 26 Jan 2014 20:52:02 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: On Sun, Jan 26, 2014 at 4:12 PM, Alexander Chemeris wrote: > For TRX1 there are no idle bursts and there should be no transmission > if there is no data sent. I can't check this right now, but I'm pretty > sure that at least some time ago osmo-trx respected this behavior and > didn't transmit on TRX1 until it gets something to transmit. Burst selection at a particular time works in the following order of priority. 1. Slot is disabled with channel combination set to NONE (default) 1. Burst exists in priority queue for the current time. 2. Filler table entry is used This ordering has never changed. What you are probably thinking of is the multi-ARFCN branch and derived code, which explicitly separated the beacon carrying channel. In that codebase, retransmissions were limited to the C0 TRX and the filler table on non-C0 channels was loaded with zeros. Osmo-TRX does not make this distinction and treats both channels are possible C0 beacons. I agree that Independent channel configuration of the filler table is the correct approach. -TT From alexander.chemeris at gmail.com Mon Jan 27 07:05:52 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 27 Jan 2014 11:05:52 +0400 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: On Mon, Jan 27, 2014 at 5:52 AM, Tom Tsou wrote: > What you are probably thinking of is the multi-ARFCN branch and > derived code, which explicitly separated the beacon carrying channel. > In that codebase, retransmissions were limited to the C0 TRX and the > filler table on non-C0 channels was loaded with zeros. Osmo-TRX does > not make this distinction and treats both channels are possible C0 > beacons. Yes, I was speaking about the multi-ARFCN branch, as that's what we tested most deeply and which we used in production. > I agree that Independent channel configuration of the filler table is > the correct approach. You mean that it'll be configurable at runtime on per-TRX basis? That'll be a nice way. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From tom at tsou.cc Mon Jan 27 03:17:48 2014 From: tom at tsou.cc (Tom Tsou) Date: Sun, 26 Jan 2014 22:17:48 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: On Sun, Jan 26, 2014 at 11:35 AM, Tom Tsou wrote: > On Sun, Jan 26, 2014 at 9:32 AM, Andreas Eversberg wrote: >> i have just tried your patch. i still get RF power on second TRX. >> osmobts-trx configures all 8 channels (SETSLOT to TCH/F), but does not send >> any burst data (TRX 1) to osmo-trx. > > Yes, that is expected behavior. There will be power output as long as > the slot is enabled. Right now the only way to turn off transmission > is to disable the slot. Hi Andreas, Please try the filler branch, which zero fills and disables filler table retransmissions by default. You can re-enable the OpenBTS type behavior for C0 on the command line. git://git.osmocom.org/osmo-trx filler -TT From andreas at eversberg.eu Thu Jan 30 07:42:52 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 30 Jan 2014 08:42:52 +0100 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: <52EA027C.1080605@eversberg.eu> Tom Tsou wrote: > Please try the filler branch, which zero fills and disables filler > table retransmissions by default. You can re-enable the OpenBTS type > behavior for C0 on the command line. just tested it. it works, i get no RF power when not sending a burst. actually i get some RF power that is 40dB lower than the power of actual bursts, but this is caused by using ARFCNs that are close. (869 and 872) From tom at tsou.cc Thu Jan 30 07:54:03 2014 From: tom at tsou.cc (Tom Tsou) Date: Thu, 30 Jan 2014 02:54:03 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: <52EA027C.1080605@eversberg.eu> References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> <52EA027C.1080605@eversberg.eu> Message-ID: On Thu, Jan 30, 2014 at 2:42 AM, Andreas Eversberg wrote: >> Please try the filler branch, which zero fills and disables filler table >> retransmissions by default. You can re-enable the OpenBTS type behavior for >> C0 on the command line. > > just tested it. it works, i get no RF power when not sending a burst. > actually i get some RF power that is 40dB lower than the power of actual > bursts, but this is caused by using ARFCNs that are close. (869 and 872) Great. It's just zero's during the non-burst periods so anything else that still shows up is probably RF related. -TT From andreas at eversberg.eu Thu Jan 30 07:31:06 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 30 Jan 2014 08:31:06 +0100 Subject: RF power problems with current master of osmo-trx In-Reply-To: References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> Message-ID: <52E9FFBA.7090904@eversberg.eu> Tom Tsou wrote: > Yes, that is expected behavior. There will be power output as long as > the slot is enabled. Right now the only way to turn off transmission > is to disable the slot. -TT hi thomas, in case of TRX 0, osmo-bts always sends bursts, even on idle bursts. it sends dummy bursts in this case. i suggest that there is no RF power in case of TRX>0 for each single burst, that is not sent from osmo-bts. the reasons are: - one TCH/H channel of one TS may be in use, so the other channel should be disabled, to reduce noise on the spectrum. - DRX (in the future) might be used to reduce noise on the spectrum. - SACCH is disabled when leaving dedicated mode, so the MS runs into radio link timeout, if the release message does not go through or some error occurs. i think about three solutions to make make osmo-trx send no RF power per burst: 1. omso-bts does not send any burst to osmo-trx 2. sends a dummy burst with lowest possible power indication (pwr=255) 3. sends a burst with zero length data (only the 6 bytes header) i prefer the first solution. best regards, andreas From tom at tsou.cc Thu Jan 30 07:35:40 2014 From: tom at tsou.cc (Tom Tsou) Date: Thu, 30 Jan 2014 02:35:40 -0500 Subject: RF power problems with current master of osmo-trx In-Reply-To: <52E9FFBA.7090904@eversberg.eu> References: <52E2328E.2090709@eversberg.eu> <52E35840.1010808@eversberg.eu> <52E36E69.8090704@eversberg.eu> <52E51C71.1030805@eversberg.eu> <52E9FFBA.7090904@eversberg.eu> Message-ID: On Thu, Jan 30, 2014 at 2:31 AM, Andreas Eversberg wrote: > in case of TRX 0, osmo-bts always sends bursts, even on idle bursts. it > sends dummy bursts in this case. i suggest that there is no RF power in case > of TRX>0 for each single burst, that is not sent from osmo-bts. the reasons > are: > > - one TCH/H channel of one TS may be in use, so the other channel should be > disabled, to reduce noise on the spectrum. > - DRX (in the future) might be used to reduce noise on the spectrum. > - SACCH is disabled when leaving dedicated mode, so the MS runs into radio > link timeout, if the release message does not go through or some error > occurs. > > i think about three solutions to make make osmo-trx send no RF power per > burst: > > 1. omso-bts does not send any burst to osmo-trx Please try out the filler branch I posted earlier. It does exactly that. -TT From jerlbeck at sysmocom.de Tue Jan 28 14:15:06 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 28 Jan 2014 15:15:06 +0100 Subject: LAPDm code issues (ladpm.c) Message-ID: <52E7BB6A.6060708@sysmocom.de> Hi LAPDm guys, while I was digging into the LAPDm code to find out, why a broken SABM message is sent on a SAPI3 establish SACCH request during an active call (leading to a delay of 3s between RSL EST request and response), I stumbled over the following: The initial SABM message (not the retransmitted one after T200) has a non-zero length and ends with 3 bytes that have been taken from the end of the RSL EST REQ message. The MS does not answer to this. Interestingly the second SABM message that gets sent after T200 (2s) has a length field of 0 and no trailing garbage. The difference lies in the way the msgb is handled. In rslms_rx_rll_est_req() the msg buffer passed from RSL is being used. In the case of IPA, the l2h is prepended by the 3 byte IPA header. Since all code in lapdm.c that handles RSL message seem to assume, that msg->data == msg->l2h, length computation is done based on that assumption in some places. In addition, msgb_pull() is used in a way that would also lead to undefined results in this case, e.g. in msgb_pull_l2h() just the difference between l2h and l3h is pulled from the beginning (msg->data). The main difficulty to find this, was that much msgb handling is done by manual access to the msgb fields. I'd really favor the use of the predefined macros/inlines instead of meddling around with the fields. I've added a function msgb_pull_to_l3() to msgb.h which just skips over everything in front of l3 (and therefore invalidates l2h and l1h) and replaced all calls to msgb_pull_l2h() by calls to msgb_pull_to_l3(). In addition, I replaced manual l3 length adjustment by calls to msgb_trim(). That alone fixed the SABM issue described above. See the jerlbeck/fixes/lapd-sms branch for details. But AFAICS there is still something to do: - The remaining msgb_pull() need to be checked (at least the one in l2_ph_data_ind() looks suspicious to me. - L3 length computation should be done with the macros, how it is done in lapdm_send_ph_data_req() is broken. - Why does lapd_msg_ctx have a length field that is not used? - ladp_test.c should be extended to check other execution paths, too. I've tried it for dummy packets and I didn't get it working without failing assertions (see below) - How l2/data/.. in a msg are expected to be used/set should be documented somewhere. - It should be clarified, whether all abis driver should reset the msg to start with l2. Cheers Jacob ====== The following patch still breaks the assertions, at least changing the l3len computation in lapdm_send_ph_data_req() influences but doesn't fix it. --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -123,8 +123,10 @@ static struct msgb *create_empty_msg(void) static struct msgb *create_dummy_data_req(void) { struct msgb *msg; + const int dummy_l1len = 3; msg = msgb_from_array(dummy1, sizeof(dummy1)); + msgb_push(msg, dummy_l1len); rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); return msg; } From jerlbeck at sysmocom.de Thu Jan 30 20:01:12 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:12 +0100 Subject: [PATCH] sms/dtap: Add log messages to analyse SMS message loss Message-ID: <1391112072-4019-1-git-send-email-jerlbeck@sysmocom.de> Incoming DTAP messages from MS are discarded during silent calls, which leads to the repeated delivery of SMS since the ACKs are not being processed. This patch adds some log messages that have been helpful to track this down. Sponsored-by: On-Waves ehf --- openbsc/src/libmsc/gsm_04_08.c | 1 + openbsc/src/libmsc/osmo_msc.c | 4 ++++ openbsc/src/libmsc/silent_call.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index bc4a9c3..cd2a0b5 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -3303,6 +3303,7 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) uint8_t pdisc = gh->proto_discr & 0x0f; int rc = 0; + LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message, pdisc=%d\n", pdisc); if (silent_call_reroute(conn, msg)) return silent_call_rx(conn, msg); diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index 31b72b9..f3badb7 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -59,6 +59,8 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg return BSC_API_CONN_POL_ACCEPT; if (trans_has_conn(conn)) return BSC_API_CONN_POL_ACCEPT; + + LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n"); return BSC_API_CONN_POL_REJECT; } @@ -71,11 +73,13 @@ static void msc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speec) { + LOGP(DRR, LOGL_DEBUG, "MSC assign complete (do nothing).\n"); } static void msc_assign_fail(struct gsm_subscriber_connection *conn, uint8_t cause, uint8_t *rr_cause) { + LOGP(DRR, LOGL_DEBUG, "MSC assign failure (do nothing).\n"); } static void msc_classmark_chg(struct gsm_subscriber_connection *conn, diff --git a/openbsc/src/libmsc/silent_call.c b/openbsc/src/libmsc/silent_call.c index cdc82b5..4462dfc 100644 --- a/openbsc/src/libmsc/silent_call.c +++ b/openbsc/src/libmsc/silent_call.c @@ -76,6 +76,7 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event, int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg) { /* FIXME: do something like sending it through a UDP port */ + LOGP(DLSMS, LOGL_NOTICE, "Discarding L3 message from a silent call.\n"); return 0; } @@ -109,6 +110,7 @@ int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg } /* otherwise, reroute */ + LOGP(DLSMS, LOGL_INFO, "Rerouting L3 message from a silent call.\n"); return 1; } @@ -136,6 +138,9 @@ int gsm_silent_call_stop(struct gsm_subscriber *subscr) if (!conn->silent_call) return -EINVAL; + DEBUGPC(DLSMS, "Stopping silent call using Timeslot %u on ARFCN %u\n", + conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn); + conn->silent_call = 0; msc_release_connection(conn); -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 30 20:01:32 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:32 +0100 Subject: [PATCH 1/5] mgcp/test: Only include conn_mode into test output Message-ID: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Currently the conn_mode and the output_enabled flags are printed to stdout. This patch modifies this to print the output_enabled flags to stderr instead. The bits in conn_mode are shown as RECV, SEND, and LOOP. This does not reduce the significance of the test, since there is an assertion already that verifies the values of the output_enabled flags with respect to the conn_mode. Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 21 +++++++++++++++------ openbsc/tests/mgcp/mgcp_test.ok | 18 +++++++++--------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index fa68867..5f69072 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -399,13 +399,22 @@ static void test_messages(void) else printf("Requested packetization period not set\n"); - if ((endp->conn_mode & CONN_UNMODIFIED) == 0) - printf("Connection mode: %d, " - "BTS output %sabled, NET output %sabled\n", + if ((endp->conn_mode & CONN_UNMODIFIED) == 0) { + printf("Connection mode: %d:%s%s%s%s\n", endp->conn_mode, - endp->bts_end.output_enabled ? "en" : "dis", - endp->net_end.output_enabled ? "en" : "dis"); - else + !endp->conn_mode ? " NONE" : "", + endp->conn_mode & MGCP_CONN_SEND_ONLY ? + " SEND" : "", + endp->conn_mode & MGCP_CONN_RECV_ONLY ? + " RECV" : "", + endp->conn_mode & MGCP_CONN_LOOPBACK & + ~MGCP_CONN_RECV_SEND ? + " LOOP" : ""); + fprintf(stderr, + "BTS output %sabled, NET output %sabled\n", + endp->bts_end.output_enabled ? "en" : "dis", + endp->net_end.output_enabled ? "en" : "dis"); + } else printf("Connection mode not set\n"); OSMO_ASSERT(endp->net_end.output_enabled == diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index fbe2566..76806f9 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -19,7 +19,7 @@ Testing CRCX Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 1, BTS output enabled, NET output disabled +Connection mode: 1: RECV Testing MDCX3 Dummy packets: 1 Packet duration not set @@ -29,35 +29,35 @@ Testing MDCX4 Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 3, BTS output enabled, NET output enabled +Connection mode: 3: SEND RECV Testing MDCX4_PT1 Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-40 -Connection mode: 3, BTS output enabled, NET output enabled +Connection mode: 3: SEND RECV Testing MDCX4_PT2 Dummy packets: 1 Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 3, BTS output enabled, NET output enabled +Connection mode: 3: SEND RECV Testing MDCX4_PT3 Dummy packets: 1 Detected packet duration: 40 Requested packetization period not set -Connection mode: 3, BTS output enabled, NET output enabled +Connection mode: 3: SEND RECV Testing MDCX4_SO Detected packet duration: 40 Requested packetetization period: 20-20 -Connection mode: 2, BTS output disabled, NET output enabled +Connection mode: 2: SEND Testing DLCX Detected packet duration: 20 Requested packetization period not set -Connection mode: 0, BTS output disabled, NET output disabled +Connection mode: 0: NONE Testing CRCX_ZYN Dummy packets: 1 Packet duration not set Requested packetization period not set -Connection mode: 1, BTS output enabled, NET output disabled +Connection mode: 1: RECV Testing EMPTY Testing SHORT1 Testing SHORT2 @@ -68,7 +68,7 @@ Testing RQNT2 Testing DLCX Detected packet duration: 20 Requested packetization period not set -Connection mode: 0, BTS output disabled, NET output disabled +Connection mode: 0: NONE Testing CRCX Re-transmitting CRCX Testing RQNT1 -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 30 20:01:33 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:33 +0100 Subject: [PATCH 2/5] mgcp/test: Fake wallclock for RTP timing/stats tests In-Reply-To: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1391112096-4059-2-git-send-email-jerlbeck@sysmocom.de> Currently the stats (jitter, transit) cannot be checked properly, since they depend on the wallclock time. This patch fakes clock_gettime (CLOCK_MONOTONIC) to reflect the scheduling time of the RTP packets. In addition, the RTP statistical value are written to stdout. A RTP test case with a SSRC change along with a reference time delay has been added. Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_test.c | 38 ++++++++++ openbsc/tests/mgcp/mgcp_test.ok | 146 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 5f69072..d1c1284 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -27,6 +27,7 @@ #include #include #include +#include char *strline_r(char *str, char **saveptr); @@ -321,6 +322,25 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); } +static int64_t force_monotonic_time_us = -1; +/* override and forward */ +int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + typedef int (*clock_gettime_t)(clockid_t clk_id, struct timespec *tp); + static clock_gettime_t real_clock_gettime = NULL; + + if (!real_clock_gettime) + real_clock_gettime = dlsym(RTLD_NEXT, "clock_gettime"); + + if (clk_id == CLOCK_MONOTONIC && force_monotonic_time_us >= 0) { + tp->tv_sec = force_monotonic_time_us / 1000000; + tp->tv_nsec = (force_monotonic_time_us % 1000000) * 1000; + return 0; + } + + return real_clock_gettime(clk_id, tp); +} + #define CONN_UNMODIFIED (0x1000) static void test_values(void) @@ -720,6 +740,17 @@ struct rtp_packet_info test_rtp_packets1[] = { /* RTP: SeqNo=25, TS=36888 */ {0.500000, 20, "\x80\x62\x00\x19\x00\x00\x90\x18\x10\x20\x30\x40" "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* SSRC changed to 0x50607080, RTP timestamp jump, Delay of 1.5s, + * SeqNo jump */ + /* RTP: SeqNo=1000, TS=160000 */ + {2.000000, 20, "\x80\x62\x03\xE8\x00\x02\x71\x00\x50\x60\x70\x80" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=1001, TS=160160 */ + {2.020000, 20, "\x80\x62\x03\xE9\x00\x02\x71\xA0\x50\x60\x70\x80" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=1002, TS=160320 */ + {2.040000, 20, "\x80\x62\x03\xEA\x00\x02\x72\x40\x50\x60\x70\x80" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, }; void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, @@ -769,6 +800,8 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { struct rtp_packet_info *info = test_rtp_packets1 + i; + force_monotonic_time_us = 1000000ULL * info->txtime; + OSMO_ASSERT(info->len <= sizeof(buffer)); OSMO_ASSERT(info->len >= 0); memmove(buffer, info->data, info->len); @@ -797,11 +830,16 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) state.in_stream.err_ts_counter - last_in_ts_err_cnt, state.out_stream.err_ts_counter - last_out_ts_err_cnt); + printf("Stats: Jitter = %u, Transit = %u\n", + mgcp_state_calc_jitter(&state), state.transit); + last_in_ts_err_cnt = state.in_stream.err_ts_counter; last_out_ts_err_cnt = state.out_stream.err_ts_counter; last_timestamp = state.out_stream.last_timestamp; last_seqno = state.out_stream.last_seq; } + + force_monotonic_time_us = -1; } int main(int argc, char **argv) diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 76806f9..6e9df8d 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -87,226 +87,372 @@ Testing packet error detection, patch SSRC. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 8, Transit = 4294967155 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967015 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967035 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 24, Transit = 4294966895 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 32, Transit = 4294966756 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 48, Transit = 4294966455 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 54, Transit = 4294966316 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 59, Transit = 4294966175 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 +Stats: Jitter = 62, Transit = 4294966076 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 67, Transit = 4294965936 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 71, Transit = 4294965795 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 76, Transit = 4294965655 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 80, Transit = 4294965515 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 83, Transit = 4294965376 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 +Stats: Jitter = 84, Transit = 4294965276 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 88, Transit = 4294965135 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 91, Transit = 4294964996 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 +Stats: Jitter = 104, Transit = 4294964696 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 106, Transit = 4294964555 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 110, Transit = 4294964395 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 104, Transit = 4294964416 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 106, Transit = 4294964275 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 108, Transit = 4294964135 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 +Stats: Jitter = 110, Transit = 4294963996 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 112, Transit = 4294963855 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 114, Transit = 4294963716 +In TS: 160000, dTS: 0, Seq: 1000 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 190, Transit = 4294965056 +In TS: 160160, dTS: 160, Seq: 1001 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 187, Transit = 4294964915 +In TS: 160320, dTS: 160, Seq: 1002 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 184, Transit = 4294964775 Testing packet error detection. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 8, Transit = 4294967155 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967015 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967035 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 24, Transit = 4294966895 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 32, Transit = 4294966756 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 48, Transit = 4294966455 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 54, Transit = 4294966316 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 59, Transit = 4294966175 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 +Stats: Jitter = 62, Transit = 4294966076 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 67, Transit = 4294965936 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 71, Transit = 4294965795 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 2126, Transit = 4294932847 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 2002, Transit = 4294932707 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1885, Transit = 4294932568 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 +Stats: Jitter = 1774, Transit = 4294932468 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1672, Transit = 4294932327 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1576, Transit = 4294932188 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 +Stats: Jitter = 1496, Transit = 4294931888 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1411, Transit = 4294931747 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1333, Transit = 4294931587 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 1251, Transit = 4294931608 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1182, Transit = 4294931467 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1117, Transit = 4294931327 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 +Stats: Jitter = 1055, Transit = 4294931188 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 998, Transit = 4294931047 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 945, Transit = 4294930908 +Output SSRC changed to 50607080 +In TS: 160000, dTS: 0, Seq: 1000 +Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 +Stats: Jitter = 8486, Transit = 4294809296 +In TS: 160160, dTS: 160, Seq: 1001 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 7965, Transit = 4294809155 +In TS: 160320, dTS: 160, Seq: 1002 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 7476, Transit = 4294809015 Testing packet error detection, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 8, Transit = 4294967155 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967015 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967035 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 24, Transit = 4294966895 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 32, Transit = 4294966756 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 48, Transit = 4294966455 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 54, Transit = 4294966316 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 59, Transit = 4294966175 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Stats: Jitter = 64, Transit = 4294966036 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 69, Transit = 4294965896 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 73, Transit = 4294965755 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 2128, Transit = 4294932807 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 2004, Transit = 4294932667 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1887, Transit = 4294932528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Stats: Jitter = 1778, Transit = 4294932388 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1676, Transit = 4294932247 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1580, Transit = 4294932108 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 +Stats: Jitter = 1500, Transit = 4294931808 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1415, Transit = 4294931667 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1336, Transit = 4294931507 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 1254, Transit = 4294931528 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1184, Transit = 4294931387 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1119, Transit = 4294931247 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 +Stats: Jitter = 1058, Transit = 4294931108 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 1000, Transit = 4294930967 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 947, Transit = 4294930828 +Output SSRC changed to 50607080 +In TS: 160000, dTS: 0, Seq: 1000 +Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 +Stats: Jitter = 8488, Transit = 4294809216 +In TS: 160160, dTS: 160, Seq: 1001 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 7966, Transit = 4294809075 +In TS: 160320, dTS: 160, Seq: 1002 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 7477, Transit = 4294808935 Testing packet error detection, patch SSRC, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 8, Transit = 4294967155 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967015 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 17, Transit = 4294967035 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 24, Transit = 4294966895 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 32, Transit = 4294966756 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 48, Transit = 4294966455 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 54, Transit = 4294966316 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 59, Transit = 4294966175 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Stats: Jitter = 64, Transit = 4294966036 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 69, Transit = 4294965896 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 73, Transit = 4294965755 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 78, Transit = 4294965615 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 81, Transit = 4294965475 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 85, Transit = 4294965336 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 +Stats: Jitter = 88, Transit = 4294965196 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 92, Transit = 4294965055 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 95, Transit = 4294964916 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 +Stats: Jitter = 107, Transit = 4294964616 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 109, Transit = 4294964475 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 113, Transit = 4294964315 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 +Stats: Jitter = 107, Transit = 4294964336 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 109, Transit = 4294964195 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 111, Transit = 4294964055 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 +Stats: Jitter = 113, Transit = 4294963916 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 114, Transit = 4294963775 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 116, Transit = 4294963636 +In TS: 160000, dTS: 0, Seq: 1000 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 192, Transit = 4294964976 +In TS: 160160, dTS: 160, Seq: 1001 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 189, Transit = 4294964835 +In TS: 160320, dTS: 160, Seq: 1002 +Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 186, Transit = 4294964695 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 30 20:01:34 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:34 +0100 Subject: [PATCH 3/5] mgcp/rtp: Fix transit computation units In-Reply-To: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1391112096-4059-3-git-send-email-jerlbeck@sysmocom.de> Currently micro-secs and RTP rate get mixed when the transit value is computed in mgcp_patch_and_count(). This patch changes get_current_ts() to accept the desired rate as argument and to use it for the time conversion instead of always converting to microseconds. If microseconds are needed, get_current_ts(1000) can be used. The arrival_time is now measured in 1/rtp_end->rate seconds so that it can be directly compared to RTP timestamps as required by RFC3550 (section 6.4.1, see definition of 'interarrival jitter'). Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 20 ++-- openbsc/tests/mgcp/mgcp_test.ok | 232 ++++++++++++++++++------------------ 2 files changed, 128 insertions(+), 124 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index b55ac04..39d5807 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -95,22 +95,25 @@ enum { /** * This does not need to be a precision timestamp and * is allowed to wrap quite fast. The returned value is - * milli seconds now. + * 1/unit seconds. */ -uint32_t get_current_ts(void) +static uint32_t get_current_ts(unsigned unit) { struct timespec tp; uint64_t ret; + if (!unit) + return 0; + memset(&tp, 0, sizeof(tp)); if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) LOGP(DMGCP, LOGL_NOTICE, "Getting the clock failed.\n"); - /* convert it to useconds */ + /* convert it to 1/unit seconds */ ret = tp.tv_sec; - ret *= 1000; - ret += tp.tv_nsec / 1000 / 1000; + ret *= unit; + ret += (int64_t)tp.tv_nsec * unit / 1000 / 1000 / 1000; return ret; } @@ -370,7 +373,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta rtp_hdr = (struct rtp_hdr *) data; seq = ntohs(rtp_hdr->sequence); timestamp = ntohl(rtp_hdr->timestamp); - arrival_time = get_current_ts(); + arrival_time = get_current_ts(rtp_end->rate); ssrc = ntohl(rtp_hdr->ssrc); if (!state->initialized) { @@ -491,9 +494,10 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta } /* - * calculate the jitter between the two packages. The TS should be + * Calculate the jitter between the two packages. The TS should be * taken closer to the read function. This was taken from the - * Appendix A of RFC 3550. The local timestamp has a usec resolution. + * Appendix A of RFC 3550. Timestamp and arrival_time have a 1/rate + * resolution. */ transit = arrival_time - timestamp; d = transit - state->transit; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 6e9df8d..7883574 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -90,91 +90,91 @@ Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 8, Transit = 4294967155 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967015 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967035 +Stats: Jitter = 10, Transit = 159 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 24, Transit = 4294966895 +Stats: Jitter = 9, Transit = 159 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 32, Transit = 4294966756 +Stats: Jitter = 8, Transit = 160 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 48, Transit = 4294966455 +Stats: Jitter = 18, Transit = 4294967295 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 54, Transit = 4294966316 +Stats: Jitter = 17, Transit = 0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 59, Transit = 4294966175 +Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 62, Transit = 4294966076 +Stats: Jitter = 17, Transit = 40 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 67, Transit = 4294965936 +Stats: Jitter = 16, Transit = 40 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 71, Transit = 4294965795 +Stats: Jitter = 15, Transit = 39 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 76, Transit = 4294965655 +Stats: Jitter = 14, Transit = 39 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 80, Transit = 4294965515 +Stats: Jitter = 13, Transit = 39 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 83, Transit = 4294965376 +Stats: Jitter = 13, Transit = 40 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 84, Transit = 4294965276 +Stats: Jitter = 14, Transit = 80 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 88, Transit = 4294965135 +Stats: Jitter = 13, Transit = 79 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 91, Transit = 4294964996 +Stats: Jitter = 13, Transit = 80 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 104, Transit = 4294964696 +Stats: Jitter = 22, Transit = 4294967216 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 106, Transit = 4294964555 +Stats: Jitter = 20, Transit = 4294967215 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 110, Transit = 4294964395 +Stats: Jitter = 29, Transit = 4294967055 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 104, Transit = 4294964416 +Stats: Jitter = 37, Transit = 4294967216 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 106, Transit = 4294964275 +Stats: Jitter = 35, Transit = 4294967215 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 108, Transit = 4294964135 +Stats: Jitter = 33, Transit = 4294967215 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 110, Transit = 4294963996 +Stats: Jitter = 31, Transit = 4294967216 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 112, Transit = 4294963855 +Stats: Jitter = 29, Transit = 4294967215 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 114, Transit = 4294963716 +Stats: Jitter = 27, Transit = 4294967216 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 190, Transit = 4294965056 +Stats: Jitter = 765, Transit = 11760 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 187, Transit = 4294964915 +Stats: Jitter = 718, Transit = 11759 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 184, Transit = 4294964775 +Stats: Jitter = 673, Transit = 11759 Testing packet error detection. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -182,93 +182,93 @@ Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 8, Transit = 4294967155 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967015 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967035 +Stats: Jitter = 10, Transit = 159 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 24, Transit = 4294966895 +Stats: Jitter = 9, Transit = 159 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 32, Transit = 4294966756 +Stats: Jitter = 8, Transit = 160 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 48, Transit = 4294966455 +Stats: Jitter = 18, Transit = 4294967295 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 54, Transit = 4294966316 +Stats: Jitter = 17, Transit = 0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 59, Transit = 4294966175 +Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 62, Transit = 4294966076 +Stats: Jitter = 17, Transit = 40 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 67, Transit = 4294965936 +Stats: Jitter = 16, Transit = 40 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 71, Transit = 4294965795 +Stats: Jitter = 15, Transit = 39 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2126, Transit = 4294932847 +Stats: Jitter = 2065, Transit = 4294934527 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2002, Transit = 4294932707 +Stats: Jitter = 1936, Transit = 4294934527 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1885, Transit = 4294932568 +Stats: Jitter = 1815, Transit = 4294934528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 1774, Transit = 4294932468 +Stats: Jitter = 1704, Transit = 4294934568 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1672, Transit = 4294932327 +Stats: Jitter = 1597, Transit = 4294934567 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1576, Transit = 4294932188 +Stats: Jitter = 1498, Transit = 4294934568 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 1496, Transit = 4294931888 +Stats: Jitter = 1414, Transit = 4294934408 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1411, Transit = 4294931747 +Stats: Jitter = 1326, Transit = 4294934407 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1333, Transit = 4294931587 +Stats: Jitter = 1253, Transit = 4294934247 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 1251, Transit = 4294931608 +Stats: Jitter = 1185, Transit = 4294934408 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1182, Transit = 4294931467 +Stats: Jitter = 1111, Transit = 4294934407 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1117, Transit = 4294931327 +Stats: Jitter = 1041, Transit = 4294934407 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 1055, Transit = 4294931188 +Stats: Jitter = 976, Transit = 4294934408 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 998, Transit = 4294931047 +Stats: Jitter = 915, Transit = 4294934407 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 945, Transit = 4294930908 +Stats: Jitter = 858, Transit = 4294934408 Output SSRC changed to 50607080 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 -Stats: Jitter = 8486, Transit = 4294809296 +Stats: Jitter = 7749, Transit = 4294823296 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7965, Transit = 4294809155 +Stats: Jitter = 7264, Transit = 4294823295 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7476, Transit = 4294809015 +Stats: Jitter = 6810, Transit = 4294823295 Testing packet error detection, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -276,93 +276,93 @@ Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 8, Transit = 4294967155 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967015 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967035 +Stats: Jitter = 10, Transit = 159 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 24, Transit = 4294966895 +Stats: Jitter = 9, Transit = 159 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 32, Transit = 4294966756 +Stats: Jitter = 8, Transit = 160 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 48, Transit = 4294966455 +Stats: Jitter = 18, Transit = 4294967295 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 54, Transit = 4294966316 +Stats: Jitter = 17, Transit = 0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 59, Transit = 4294966175 +Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 64, Transit = 4294966036 +Stats: Jitter = 15, Transit = 0 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 69, Transit = 4294965896 +Stats: Jitter = 14, Transit = 0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 73, Transit = 4294965755 +Stats: Jitter = 13, Transit = 4294967295 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2128, Transit = 4294932807 +Stats: Jitter = 2063, Transit = 4294934487 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2004, Transit = 4294932667 +Stats: Jitter = 1934, Transit = 4294934487 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1887, Transit = 4294932528 +Stats: Jitter = 1813, Transit = 4294934488 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 1778, Transit = 4294932388 +Stats: Jitter = 1700, Transit = 4294934488 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1676, Transit = 4294932247 +Stats: Jitter = 1593, Transit = 4294934487 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1580, Transit = 4294932108 +Stats: Jitter = 1494, Transit = 4294934488 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 1500, Transit = 4294931808 +Stats: Jitter = 1411, Transit = 4294934328 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1415, Transit = 4294931667 +Stats: Jitter = 1322, Transit = 4294934327 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1336, Transit = 4294931507 +Stats: Jitter = 1250, Transit = 4294934167 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 1254, Transit = 4294931528 +Stats: Jitter = 1182, Transit = 4294934328 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1184, Transit = 4294931387 +Stats: Jitter = 1108, Transit = 4294934327 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1119, Transit = 4294931247 +Stats: Jitter = 1039, Transit = 4294934327 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 1058, Transit = 4294931108 +Stats: Jitter = 974, Transit = 4294934328 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1000, Transit = 4294930967 +Stats: Jitter = 913, Transit = 4294934327 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 947, Transit = 4294930828 +Stats: Jitter = 856, Transit = 4294934328 Output SSRC changed to 50607080 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 -Stats: Jitter = 8488, Transit = 4294809216 +Stats: Jitter = 7747, Transit = 4294823216 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7966, Transit = 4294809075 +Stats: Jitter = 7263, Transit = 4294823215 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7477, Transit = 4294808935 +Stats: Jitter = 6809, Transit = 4294823215 Testing packet error detection, patch SSRC, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -370,89 +370,89 @@ Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0 Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 8, Transit = 4294967155 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967015 +Stats: Jitter = 0, Transit = 4294967295 In TS: 320, dTS: 160, Seq: 3 Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967035 +Stats: Jitter = 10, Transit = 159 In TS: 480, dTS: 160, Seq: 4 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 24, Transit = 4294966895 +Stats: Jitter = 9, Transit = 159 In TS: 640, dTS: 160, Seq: 5 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 32, Transit = 4294966756 +Stats: Jitter = 8, Transit = 160 In TS: 960, dTS: 320, Seq: 6 Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 48, Transit = 4294966455 +Stats: Jitter = 18, Transit = 4294967295 In TS: 1120, dTS: 160, Seq: 7 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 54, Transit = 4294966316 +Stats: Jitter = 17, Transit = 0 In TS: 1280, dTS: 160, Seq: 8 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 59, Transit = 4294966175 +Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 64, Transit = 4294966036 +Stats: Jitter = 15, Transit = 0 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 69, Transit = 4294965896 +Stats: Jitter = 14, Transit = 0 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 73, Transit = 4294965755 +Stats: Jitter = 13, Transit = 4294967295 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 78, Transit = 4294965615 +Stats: Jitter = 12, Transit = 4294967295 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 81, Transit = 4294965475 +Stats: Jitter = 11, Transit = 4294967295 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 85, Transit = 4294965336 +Stats: Jitter = 11, Transit = 0 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 88, Transit = 4294965196 +Stats: Jitter = 10, Transit = 0 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 92, Transit = 4294965055 +Stats: Jitter = 9, Transit = 4294967295 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 95, Transit = 4294964916 +Stats: Jitter = 9, Transit = 0 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 107, Transit = 4294964616 +Stats: Jitter = 18, Transit = 4294967136 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 109, Transit = 4294964475 +Stats: Jitter = 17, Transit = 4294967135 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 113, Transit = 4294964315 +Stats: Jitter = 26, Transit = 4294966975 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 107, Transit = 4294964336 +Stats: Jitter = 34, Transit = 4294967136 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 109, Transit = 4294964195 +Stats: Jitter = 32, Transit = 4294967135 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 111, Transit = 4294964055 +Stats: Jitter = 30, Transit = 4294967135 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 113, Transit = 4294963916 +Stats: Jitter = 28, Transit = 4294967136 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 114, Transit = 4294963775 +Stats: Jitter = 27, Transit = 4294967135 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 116, Transit = 4294963636 +Stats: Jitter = 25, Transit = 4294967136 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 192, Transit = 4294964976 +Stats: Jitter = 763, Transit = 11680 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 189, Transit = 4294964835 +Stats: Jitter = 716, Transit = 11679 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 186, Transit = 4294964695 +Stats: Jitter = 671, Transit = 11679 Done -- 1.7.9.5 From holger at freyther.de Fri Jan 31 10:36:34 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 31 Jan 2014 11:36:34 +0100 Subject: [PATCH 3/5] mgcp/rtp: Fix transit computation units In-Reply-To: <1391112096-4059-3-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> <1391112096-4059-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140131103634.GB26491@xiaoyu.lan> On Thu, Jan 30, 2014 at 09:01:34PM +0100, Jacob Erlbeck wrote: Hi jacob! > This patch changes get_current_ts() to accept the desired rate as > argument and to use it for the time conversion instead of always > converting to microseconds. If microseconds are needed, > get_current_ts(1000) can be used. > The arrival_time is now measured in 1/rtp_end->rate seconds so that > it can be directly compared to RTP timestamps as required by RFC3550 > (section 6.4.1, see definition of 'interarrival jitter'). thanks for spotting this issue while working on related code. I am embarassed. It appears that the transmit time was already drifting apart. From jerlbeck at sysmocom.de Thu Jan 30 20:01:35 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:35 +0100 Subject: [PATCH 4/5] mgcp/rtp: Compute delta timestamp based on wallclock In-Reply-To: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1391112096-4059-4-git-send-email-jerlbeck@sysmocom.de> Currently, when the SSRC changes within a stream and SSRC fixing is enabled, the RTP timestamp between the last packet the has been received with the old SSRC and the first packet of the new SSRC is always incremented by one packet duration. This can lead to audio muting (at least with the nanoBTS) when the wallclock interval between these packets is too large (> 1s). This patch change the implementation to base the RTP timestamp offset on the wallclock interval that has passed between these two packets. Ticket: OW#466 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 1 + openbsc/src/libmgcp/mgcp_network.c | 12 ++++++++++-- openbsc/tests/mgcp/mgcp_test.ok | 16 ++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 28ea678..9b97165 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -46,6 +46,7 @@ struct mgcp_rtp_stream_state { uint32_t last_timestamp; uint32_t err_ts_counter; int32_t last_tsdelta; + uint32_t last_arrival_time; }; struct mgcp_rtp_state { diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 39d5807..5363fb8 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -415,10 +415,17 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->in_stream.ssrc = ssrc; if (rtp_end->force_constant_ssrc) { - const int16_t delta_seq = 1; + int16_t delta_seq; + /* Always increment seqno by 1 */ state->seq_offset = - (state->out_stream.last_seq + delta_seq) - seq; + (state->out_stream.last_seq + 1) - seq; + + /* Estimate number of packets that would have been sent */ + delta_seq = + (arrival_time - state->in_stream.last_arrival_time + + state->packet_duration/2) / + state->packet_duration; adjust_rtp_timestamp_offset(endp, state, rtp_end, addr, delta_seq, timestamp); @@ -452,6 +459,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta /* Save before patching */ state->in_stream.last_timestamp = timestamp; state->in_stream.last_seq = seq; + state->in_stream.last_arrival_time = arrival_time; if (rtp_end->force_aligned_timing && state->out_stream.ssrc == ssrc && state->packet_duration) diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 7883574..e383fb5 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -167,14 +167,14 @@ In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Stats: Jitter = 27, Transit = 4294967216 In TS: 160000, dTS: 0, Seq: 1000 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 765, Transit = 11760 +Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 25, Transit = 4294967216 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 718, Transit = 11759 +Stats: Jitter = 24, Transit = 4294967215 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 673, Transit = 11759 +Stats: Jitter = 22, Transit = 4294967215 Testing packet error detection. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -447,12 +447,12 @@ In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Stats: Jitter = 25, Transit = 4294967136 In TS: 160000, dTS: 0, Seq: 1000 -Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 763, Transit = 11680 +Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0 +Stats: Jitter = 23, Transit = 4294967136 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 716, Transit = 11679 +Stats: Jitter = 22, Transit = 4294967135 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 671, Transit = 11679 +Stats: Jitter = 21, Transit = 4294967135 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Jan 30 20:01:36 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Jan 2014 21:01:36 +0100 Subject: [PATCH 5/5] mgcp/rtp: Base jitter calculation on input timestamps In-Reply-To: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1391112096-4059-5-git-send-email-jerlbeck@sysmocom.de> So far, the jitter computation has been based on output timestamps. This patch uses the input timestamps instead and resets jitter computation on SSRC changes. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 6 +- openbsc/tests/mgcp/mgcp_test.ok | 156 ++++++++++++++++++------------------ 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 5363fb8..8a5656a 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -375,6 +375,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta timestamp = ntohl(rtp_hdr->timestamp); arrival_time = get_current_ts(rtp_end->rate); ssrc = ntohl(rtp_hdr->ssrc); + transit = arrival_time - timestamp; if (!state->initialized) { state->in_stream.last_seq = seq - 1; @@ -383,7 +384,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->base_seq = seq; state->initialized = 1; state->jitter = 0; - state->transit = arrival_time - timestamp; + state->transit = transit; state->packet_duration = mgcp_rtp_packet_duration(endp, rtp_end); state->out_stream = state->in_stream; state->out_stream.last_timestamp = timestamp; @@ -414,6 +415,8 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta endp->conn_mode); state->in_stream.ssrc = ssrc; + state->jitter = 0; + state->transit = transit; if (rtp_end->force_constant_ssrc) { int16_t delta_seq; @@ -507,7 +510,6 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta * Appendix A of RFC 3550. Timestamp and arrival_time have a 1/rate * resolution. */ - transit = arrival_time - timestamp; d = transit - state->transit; state->transit = transit; if (d < 0) diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index e383fb5..2c30115 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -123,58 +123,58 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Stats: Jitter = 15, Transit = 39 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 14, Transit = 39 +Stats: Jitter = 0, Transit = 4294934527 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 39 +Stats: Jitter = 0, Transit = 4294934527 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 40 +Stats: Jitter = 0, Transit = 4294934528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 14, Transit = 80 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 79 +Stats: Jitter = 2, Transit = 4294934567 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 80 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 22, Transit = 4294967216 +Stats: Jitter = 12, Transit = 4294934408 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 20, Transit = 4294967215 +Stats: Jitter = 11, Transit = 4294934407 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 29, Transit = 4294967055 +Stats: Jitter = 20, Transit = 4294934247 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 37, Transit = 4294967216 +Stats: Jitter = 29, Transit = 4294934408 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 35, Transit = 4294967215 +Stats: Jitter = 27, Transit = 4294934407 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 33, Transit = 4294967215 +Stats: Jitter = 26, Transit = 4294934407 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 31, Transit = 4294967216 +Stats: Jitter = 24, Transit = 4294934408 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 29, Transit = 4294967215 +Stats: Jitter = 23, Transit = 4294934407 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 27, Transit = 4294967216 +Stats: Jitter = 21, Transit = 4294934408 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 25, Transit = 4294967216 +Stats: Jitter = 0, Transit = 4294823296 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 24, Transit = 4294967215 +Stats: Jitter = 0, Transit = 4294823295 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 22, Transit = 4294967215 +Stats: Jitter = 0, Transit = 4294823295 Testing packet error detection. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -216,59 +216,59 @@ Stats: Jitter = 15, Transit = 39 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2065, Transit = 4294934527 +Stats: Jitter = 0, Transit = 4294934527 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1936, Transit = 4294934527 +Stats: Jitter = 0, Transit = 4294934527 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1815, Transit = 4294934528 +Stats: Jitter = 0, Transit = 4294934528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1 -Stats: Jitter = 1704, Transit = 4294934568 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1597, Transit = 4294934567 +Stats: Jitter = 2, Transit = 4294934567 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1498, Transit = 4294934568 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 1414, Transit = 4294934408 +Stats: Jitter = 12, Transit = 4294934408 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1326, Transit = 4294934407 +Stats: Jitter = 11, Transit = 4294934407 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1253, Transit = 4294934247 +Stats: Jitter = 20, Transit = 4294934247 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 1185, Transit = 4294934408 +Stats: Jitter = 29, Transit = 4294934408 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1111, Transit = 4294934407 +Stats: Jitter = 27, Transit = 4294934407 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1041, Transit = 4294934407 +Stats: Jitter = 26, Transit = 4294934407 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 976, Transit = 4294934408 +Stats: Jitter = 24, Transit = 4294934408 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 915, Transit = 4294934407 +Stats: Jitter = 23, Transit = 4294934407 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 858, Transit = 4294934408 +Stats: Jitter = 21, Transit = 4294934408 Output SSRC changed to 50607080 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 -Stats: Jitter = 7749, Transit = 4294823296 +Stats: Jitter = 0, Transit = 4294823296 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7264, Transit = 4294823295 +Stats: Jitter = 0, Transit = 4294823295 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 6810, Transit = 4294823295 +Stats: Jitter = 0, Transit = 4294823295 Testing packet error detection, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -300,69 +300,69 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 15, Transit = 0 +Stats: Jitter = 17, Transit = 40 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 14, Transit = 0 +Stats: Jitter = 16, Transit = 40 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 4294967295 +Stats: Jitter = 15, Transit = 39 Output SSRC changed to 10203040 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 2063, Transit = 4294934487 +Stats: Jitter = 0, Transit = 4294934527 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1934, Transit = 4294934487 +Stats: Jitter = 0, Transit = 4294934527 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1813, Transit = 4294934488 +Stats: Jitter = 0, Transit = 4294934528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 1700, Transit = 4294934488 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1593, Transit = 4294934487 +Stats: Jitter = 2, Transit = 4294934567 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1494, Transit = 4294934488 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 1411, Transit = 4294934328 +Stats: Jitter = 12, Transit = 4294934408 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1322, Transit = 4294934327 +Stats: Jitter = 11, Transit = 4294934407 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1250, Transit = 4294934167 +Stats: Jitter = 20, Transit = 4294934247 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 1182, Transit = 4294934328 +Stats: Jitter = 29, Transit = 4294934408 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1108, Transit = 4294934327 +Stats: Jitter = 27, Transit = 4294934407 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 1039, Transit = 4294934327 +Stats: Jitter = 26, Transit = 4294934407 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 974, Transit = 4294934328 +Stats: Jitter = 24, Transit = 4294934408 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 913, Transit = 4294934327 +Stats: Jitter = 23, Transit = 4294934407 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 856, Transit = 4294934328 +Stats: Jitter = 21, Transit = 4294934408 Output SSRC changed to 50607080 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0 -Stats: Jitter = 7747, Transit = 4294823216 +Stats: Jitter = 0, Transit = 4294823296 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 7263, Transit = 4294823215 +Stats: Jitter = 0, Transit = 4294823295 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 6809, Transit = 4294823215 +Stats: Jitter = 0, Transit = 4294823295 Testing packet error detection, patch SSRC, patch timestamps. Output SSRC changed to 11223344 In TS: 0, dTS: 0, Seq: 0 @@ -394,65 +394,65 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Stats: Jitter = 16, Transit = 4294967295 In TS: 1400, dTS: 120, Seq: 9 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 15, Transit = 0 +Stats: Jitter = 17, Transit = 40 In TS: 1560, dTS: 160, Seq: 10 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 14, Transit = 0 +Stats: Jitter = 16, Transit = 40 In TS: 1720, dTS: 160, Seq: 11 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 13, Transit = 4294967295 +Stats: Jitter = 15, Transit = 39 In TS: 34688, dTS: 0, Seq: 12 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 12, Transit = 4294967295 +Stats: Jitter = 0, Transit = 4294934527 In TS: 34848, dTS: 160, Seq: 13 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 11, Transit = 4294967295 +Stats: Jitter = 0, Transit = 4294934527 In TS: 35008, dTS: 160, Seq: 14 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 11, Transit = 0 +Stats: Jitter = 0, Transit = 4294934528 In TS: 35128, dTS: 120, Seq: 15 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0 -Stats: Jitter = 10, Transit = 0 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35288, dTS: 160, Seq: 16 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 9, Transit = 4294967295 +Stats: Jitter = 2, Transit = 4294934567 In TS: 35448, dTS: 160, Seq: 17 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 9, Transit = 0 +Stats: Jitter = 2, Transit = 4294934568 In TS: 35768, dTS: 160, Seq: 19 Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0 -Stats: Jitter = 18, Transit = 4294967136 +Stats: Jitter = 12, Transit = 4294934408 In TS: 35928, dTS: 160, Seq: 20 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967135 +Stats: Jitter = 11, Transit = 4294934407 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 26, Transit = 4294966975 +Stats: Jitter = 20, Transit = 4294934247 In TS: 36088, dTS: 160, Seq: 21 Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0 -Stats: Jitter = 34, Transit = 4294967136 +Stats: Jitter = 29, Transit = 4294934408 In TS: 36248, dTS: 160, Seq: 22 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 32, Transit = 4294967135 +Stats: Jitter = 27, Transit = 4294934407 In TS: 36408, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 30, Transit = 4294967135 +Stats: Jitter = 26, Transit = 4294934407 In TS: 36568, dTS: 160, Seq: 23 Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1 -Stats: Jitter = 28, Transit = 4294967136 +Stats: Jitter = 24, Transit = 4294934408 In TS: 36728, dTS: 160, Seq: 24 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 27, Transit = 4294967135 +Stats: Jitter = 23, Transit = 4294934407 In TS: 36888, dTS: 160, Seq: 25 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 25, Transit = 4294967136 +Stats: Jitter = 21, Transit = 4294934408 In TS: 160000, dTS: 0, Seq: 1000 Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 23, Transit = 4294967136 +Stats: Jitter = 0, Transit = 4294823296 In TS: 160160, dTS: 160, Seq: 1001 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 22, Transit = 4294967135 +Stats: Jitter = 0, Transit = 4294823295 In TS: 160320, dTS: 160, Seq: 1002 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 21, Transit = 4294967135 +Stats: Jitter = 0, Transit = 4294823295 Done -- 1.7.9.5 From holger at freyther.de Fri Jan 31 10:34:38 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 31 Jan 2014 11:34:38 +0100 Subject: [PATCH 1/5] mgcp/test: Only include conn_mode into test output In-Reply-To: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140131103438.GA26491@xiaoyu.lan> On Thu, Jan 30, 2014 at 09:01:32PM +0100, Jacob Erlbeck wrote: hi jacob! > This patch modifies this to print the output_enabled flags to stderr > instead. The bits in conn_mode are shown as RECV, SEND, and LOOP. > This does not reduce the significance of the test, since there is an > assertion already that verifies the values of the output_enabled > flags with respect to the conn_mode. there is no occurrence of "LOOP" in the testcase (and it can't be trigerred through mgcp anyway?). > + endp->conn_mode & MGCP_CONN_LOOPBACK & > + ~MGCP_CONN_RECV_SEND ? Why the & ~MGCP_CONN_RECV_SEND? From mihal.grznar at gmail.com Fri Jan 31 15:10:50 2014 From: mihal.grznar at gmail.com (=?ISO-8859-1?Q?Michal_Grzn=E1r?=) Date: Fri, 31 Jan 2014 16:10:50 +0100 Subject: osmoSGSN Message-ID: Hi, I am trying to use osmoSGSN in topology with openGGSN and sim-bss, which is simulator of BSS made by company Alcatel-Lucent. I have a problem that my osmoSGSN can not communicate with sim-BSS and it can not connect correctly. It is caused by non function bssgp. I would like to ask you, how can I configure bssgp on osmoSGSN? I can configure ns states also from vty on osmoSGSN but I can not bssgp states such as bvci etc...Please could you help me? I hope you will reply me soon. Thank you very much Best regards, Michal Grzn?r -------------- next part -------------- An HTML attachment was scrubbed... URL: