From zero-kelvin at gmx.de Fri Nov 22 21:06:23 2013 From: zero-kelvin at gmx.de (dexter) Date: Fri, 22 Nov 2013 22:06:23 +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: <528FC74F.3090705@gmx.de> Hi All. It's time Again! This is the announcement for the next Osmocom Berlin meeting. Nov 27, 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 jean_dessal at yahoo.fr Sun Nov 17 18:35:57 2013 From: jean_dessal at yahoo.fr (Jean) Date: Sun, 17 Nov 2013 18:35:57 +0000 (UTC) Subject: Hard reset NanoBTS after forgetting static IP References: <0B9AC9F7-BD29-4A62-8708-A99B7E79163C@bongiorni.eu> Message-ID: Luca Bongiorni bongiorni.eu> writes: > > > Hey there, > I have come across a nanoBTS 165AU but since is used and not tested from the previous owner, I guess it has set a > static IP. > After turned on is booting (RED light) and then remains (ORANGE not flashing) even if the eth is connected to > the router. > > At the moment I am trying with ipaccess-find and BtsInstaller to find in on my LAN . > Unfortunately it is not answering and is not even getting an IP from the router by the DHCP daemon. > > Two possibilities, I have thought: > an hw/sw issue; > a Static IP is set. > > Supposing that is the 2nd possibility, I was thinking: > to change private class of my LAN, to see if it changes something; > to make an hard reset of the bts. > > Do you know if it possible to reset in someway? > Ever happened this issue to you guys? > Suggestions or insults are welcome. > > Thanks in advance. > Cheers, > Luca > > P.S.: I don't recall exactly, but one time I heard that is possible to reset by short-circuiting some pins of > the LAN/48VDC eth connector. Is it right?! > Hi Luca; Kindly is it possible to share the procedure you use to configure your NanoBTS? I have one from ip.access to commissioner and put in service but I don't have any procedure. my email is jean_dessal at yahoo.fr Thanks in advance Jean From ml at mail.tsaitgaist.info Tue Nov 19 16:43:38 2013 From: ml at mail.tsaitgaist.info (Kevin Redon) Date: Tue, 19 Nov 2013 17:43:38 +0100 Subject: Hard reset NanoBTS after forgetting static IP In-Reply-To: References: <0B9AC9F7-BD29-4A62-8708-A99B7E79163C@bongiorni.eu> Message-ID: <1384879306-sup-9008@dennou> Excerpts from Jean's message of 2013-11-17 19:35:57 +0100: > > P.S.: I don't recall exactly, but one time I heard that is possible to > reset by short-circuiting some pins of > > the LAN/48VDC eth connector. Is it right?! > > Here the procedure I used to reset the configuration of my nanoBTS (which defaults to DHCP): - power off the nanoBTS - short the pin 9+10 on the TIB+IN port (the one farest away from TIB+OUT). You could use a 10P10C connector (RJ50/RJ69). I used a small flat screwdriver. - power on the nanoBTS. The boot (LED on RED) will take longer then usual. At the end the LED will blink RED rapidly - power off the nanoBTS - remove the short from TIB+IN - power up the nanoBTS - it will be reseted (the LED will first be RED will booting, then blink red/green to tell that the UID has not been set hope it helps, kevin From alexander.huemer at xx.vu Fri Nov 22 09:20:07 2013 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Fri, 22 Nov 2013 10:20:07 +0100 Subject: Hard reset NanoBTS after forgetting static IP In-Reply-To: <1384879306-sup-9008@dennou> References: <0B9AC9F7-BD29-4A62-8708-A99B7E79163C@bongiorni.eu> <1384879306-sup-9008@dennou> Message-ID: <20131122092007.GB5149@yade.xx.vu> On Tue, Nov 19, 2013 at 05:43:38PM +0100, Kevin Redon wrote: > Excerpts from Jean's message of 2013-11-17 19:35:57 +0100: > > > P.S.: I don't recall exactly, but one time I heard that is possible to > > reset by short-circuiting some pins of > > > the LAN/48VDC eth connector. Is it right?! > > > > > Here the procedure I used to reset the configuration of my nanoBTS > (which defaults to DHCP): > [...] I added this to the wiki[1], somebody might want to look it up. Kind regards, -Alex [1] https://openbsc.osmocom.org/trac/wiki/nanoBTS From alex at vandijl.com Fri Nov 22 09:23:40 2013 From: alex at vandijl.com (Alexander van Dijl) Date: Fri, 22 Nov 2013 10:23:40 +0100 Subject: Hard reset NanoBTS after forgetting static IP In-Reply-To: <20131122092007.GB5149@yade.xx.vu> References: <0B9AC9F7-BD29-4A62-8708-A99B7E79163C@bongiorni.eu> <1384879306-sup-9008@dennou> <20131122092007.GB5149@yade.xx.vu> Message-ID: Hi! Could someone help me get off this list? An old collegue of mine subscribed but he has left the business. The subscibed email address is albert at vraagalex.nl. Alex Meer weten over mij? Website: http://vraagalex.nl - Het alternatief voor 0900-nummers LinkedIn: http://linkedin.com/in/vraagalex Facebook: http://facebook.com/vraagalex 2013/11/22 Alexander Huemer > On Tue, Nov 19, 2013 at 05:43:38PM +0100, Kevin Redon wrote: > > Excerpts from Jean's message of 2013-11-17 19:35:57 +0100: > > > > P.S.: I don't recall exactly, but one time I heard that is possible > to > > > reset by short-circuiting some pins of > > > > the LAN/48VDC eth connector. Is it right?! > > > > > > > > Here the procedure I used to reset the configuration of my nanoBTS > > (which defaults to DHCP): > > [...] > > I added this to the wiki[1], somebody might want to look it up. > > Kind regards, > -Alex > > [1] https://openbsc.osmocom.org/trac/wiki/nanoBTS > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.huemer at xx.vu Fri Nov 22 20:36:05 2013 From: alexander.huemer at xx.vu (Alexander Huemer) Date: Fri, 22 Nov 2013 21:36:05 +0100 Subject: Hard reset NanoBTS after forgetting static IP In-Reply-To: References: <0B9AC9F7-BD29-4A62-8708-A99B7E79163C@bongiorni.eu> <1384879306-sup-9008@dennou> <20131122092007.GB5149@yade.xx.vu> Message-ID: <20131122203605.GA2747@yade.xx.vu> On Fri, Nov 22, 2013 at 10:23:40AM +0100, Alexander van Dijl wrote: > Could someone help me get off this list? An old collegue of mine > subscribed but he has left the business. > > The subscibed email address is albert at vraagalex.nl. Visit [1]. The instructions to unsubscribe are there. Kind regards, -Alex [1] http://lists.osmocom.org/mailman/listinfo/openbsc From laforge at gnumonks.org Sun Nov 3 14:23:57 2013 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 3 Nov 2013 15:23:57 +0100 Subject: [PATCH 4/5] msc: Do not store received id in the SMS database. In-Reply-To: References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-5-git-send-email-Alexander.Chemeris@gmail.com> <20131008100301.GE6194@xiaoyu.lan> Message-ID: <20131103142357.GC7342@nataraja.gnumonks.org> Hi Alexander, a bit of a late response, but > On the similar venue, I'm thinking about delivering SMS to SMPP over > unstable links (e.g. satellite), where the link may be inaccessible > for non-negligible amounts of time. To make this usable, we need a > queue in front of the SMPP interface. I would appreciate if that could be handled outside osmo-nitb by something like a stand-alone SMPP caching proxy. This proxy would behave as an SMPP ESMSE, accept any MO-SMS from the NITB, cache it locally and postpone delivery to the real ESME. This way OsmoNITB doesn't have to add code specifically for that situation. -- - 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 Tue Nov 5 06:30:42 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Tue, 05 Nov 2013 07:30:42 +0100 Subject: OpenBSC + LCR + Asterisk = half sided calls in one direction In-Reply-To: <236165582.20131027114647@freemail.hu> References: <236165582.20131027114647@freemail.hu> Message-ID: <52789092.4090908@eversberg.eu> Sipos Csaba wrote: > But when the SIP phones initiates a voice call towards the GSM phone, > only the SIP phone can hear the voice of the GSM phone, and not the > other way around (half sided call). The connection setup works both > ways just fine. > > hi sipos, can you start LCR, do one call towards GSM phone and send the /usr/local/var/log/lcr/log file part of this call? regards, andreas From andreas at eversberg.eu Wed Nov 6 06:40:15 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Wed, 06 Nov 2013 07:40:15 +0100 Subject: New handover algorithm with Nokia BTS In-Reply-To: <1775378469.20131029113345@freemail.hu> References: <1775378469.20131029113345@freemail.hu> Message-ID: <5279E44F.8040105@eversberg.eu> Sipos Csaba wrote: > I just wanted to ask before I spend a lot of time with it. Does the > new HO algorithm also works with non-IP based BTSes like Nokia metro > or insite? Or at least in theory it should work? > > Because the handover is not working with the current algo for Nokia, I > want to give the new one a try. > > Csaba > > > hi sipos, both handover algorithms (old and new) are available in my jolly/new_handover branch, they can be enabled globally via VTY at network level. the handover logic, which actually controls BTS and MS during handover, is the same for both algorithms. i have never tested the handover logic with BS11 or nokia, but i cannot see why it should not work. regards, andreas From laforge at gnumonks.org Thu Nov 7 19:15:28 2013 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 7 Nov 2013 20:15:28 +0100 Subject: Openbsc support for new BTS In-Reply-To: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> Message-ID: <20131107191528.GB5624@nataraja.gnumonks.org> hi Jason, sorry for the one week delay, but I've been super busy and have not been able to follow the mailing lists as much as I used to. > I have been going through your Osmocom projects especially Openbsc > (osmo-nitb) and Osmobts projects and I must say it's a real great > work! On behalf of the teams behind that software: Thanks for the compliments! > I'm a lead engineer at Octasic and after looking at your work on > OpenBSC and OsmoBTS, we decided to use your OpenBSC stack for internal > testing of our Octasic PHY. Great. It is probably not your responsibility, but I would actually hope that you not only consider it for internal testing but also as one possible choice for your customers ;) > I know currently openbsc supports few BTS models like ip.access, > sysmocom etc. I have gone through the wiki and some of the openbsc > archives. I could find an archive regarding Octasic SDR, but I guess > it has not gone any further. > http://lists.osmocom.org/pipermail/openbsc/2010-November/002196.html I am not aware of anyone having done any work in that area, no. > I will be interested in osmo-nitb which I can use for network part of > GSM and use osmo-bts for BTS L2/L3 stuff, which already has > abis-over-ip interface to openBSC(osmo-nitb). I have Octasic SDR > hardware that has the layer1 (DSP image), so all I need to implement > is the interfaces between Octasic Layer1 and osmobts L2/L3 to > communicate between them, which I'm working on. This is good news! It is probably worthwhile to use the trx branch that jolly (Andreas) is working on for adding new L1 interfaces. The master branch has many parts that are actually not sysmobts specific in the sysmobts specific part of the source, and Andreas' branch is introducing a new interface (l1 sap) to resolve this. > I have already installed openbsc (osmo-nitb) and also osmobts on my > Debian 7.1.0. I'm currently in a process of writing interfaces between > Octasic L1 and osmobts. great. Please note, the l1sap / trx branch of jolly is definitely going to make it easier for you. > At present I'm trying to get TRX config request from osmo-nitb. > However though I'm receiving few OML messages like NM_MT_SET_BTS_ATTR > (pcap attached), I guess they are specific to ip.access BTS, I'm not > able to see any TRX config request coming from osmo-nitb (Or by any > chance is that what I'm receiving is the TRX config one?) The wirshark OML dissector should decode all the messages, even the IPA specific ones. Please check the wireshark A-bis OML dissector preferences for 'use nanoBTS definitions' or something along those lines. > I'm simply sending ack for those OML messages and eventually expecting > a TRX config request from osmo-nitb. I'm not sure if osmo-nitb expects > something to se sent from BTS side, looks like it is simply waiting > for something(see below). Please check the wiki, I _thought_ we had pcap files of OML startup with a nanoBTS online somewhere. If you cannot find it, please ask here on the mailinglist for somebody with sysmoBTS or nanoBTS to provide you a startup trace. > <0005> abis_nm.c:1442 Set BTS Attr (bts=0) <0005> abis_nm.c:1763 > OC=BTS(01) INST=(00,ff,ff) Sending OPSTART Please refer to the TS 12.21 specification. When an OPSTART is sent from BSC to BTS, you need to transition the operational state of the respective MO (managed objects) and indicate that back to the BSC. > I'm expecting 1st message, TRX config request from osmo-nitb and do > not see it. I was thinking, once the abis interface is up (OML link), > osmo-nitb will trigger TRX configuration and then based on the > response from BTS, other configurations. Does osmo-nitb require some > kind of handshake from the BTS side to send the TRX configuration? there is no single 'trx configuration' message, but a fairly intricate system of hierarchical managed objects that have to transition their state in the correct order. Both osmo-bts as well as OpenBSC are only doing a half-way decent job at implementing them. 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 Fri Nov 8 16:17:46 2013 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 8 Nov 2013 17:17:46 +0100 Subject: Openbsc support for new BTS In-Reply-To: <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> Message-ID: <20131108161746.GM5624@nataraja.gnumonks.org> Hi Jason, On Fri, Nov 08, 2013 at 01:21:46PM +0000, Jason DSouza wrote: > But I'm waiting at Opstart for Obj Class - RADIO_CARRIER to trigger > trx-init() which is never received from BSC. That is where I'm struck > now. All this so far is similar to sysmobts interface, something > similar to bts_model_opstart() function in osmo-bts-sysmo. Please see the following code from bts_ipaccess_nanobts.c: ============== /* Callback function to be called whenever we get a GSM 12.21 state change event */ static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd) { [...] case NM_OC_RADIO_CARRIER: trx = obj; if (new_state->operational == NM_OPSTATE_DISABLED && new_state->availability == NM_AVSTATE_OK) abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr, trx->nr, 0xff); break; ============== So the opstrart for the RADIO_CARRIER is sent in response to an incoming NM_MT_STATECHG_EVENT_REP withe the operational state set to DISABLED and the availability set to OK. My guess is that you are not sending such a state event from the BTS to the BSC. I can also not see that in the pcap file you have sent. All OML messages in there relate to the Site MAnager or the BTS object class, but there are no messages related to any other MOs. As indicated, it is best to start from a known-working setup with a supported BTS model, or at least from a protocol trace of an existing supported configuration. Please also make sure to set your 'bts model' to nanobts, I _think_ the 'bts model sysmobts' is still broken. 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 holger at freyther.de Fri Nov 8 17:33:30 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 8 Nov 2013 18:33:30 +0100 Subject: Openbsc support for new BTS In-Reply-To: <20131108161746.GM5624@nataraja.gnumonks.org> References: <813F249CA3F4814F9249E5253FFA7CC2496EA33A@MAIL2.octasic.com> <20131107191528.GB5624@nataraja.gnumonks.org> <813F249CA3F4814F9249E5253FFA7CC24970648D@MAIL2.octasic.com> <20131108161746.GM5624@nataraja.gnumonks.org> Message-ID: <20131108173330.GI16696@xiaoyu.lan> On Fri, Nov 08, 2013 at 05:17:46PM +0100, Harald Welte wrote: > Please also make sure to set your 'bts model' to nanobts, I _think_ the > 'bts model sysmobts' is still broken. nope. I fixed it, even in mixed nanobts/sysmobts operation. From jerlbeck at sysmocom.de Mon Nov 4 13:56:09 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 14:56:09 +0100 Subject: [PATCH 1/4] femto: Add L1P_T_INVALID to l1prim_type Message-ID: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> Currently uninitialized elements of the femtobts_sysprim_type array are mistaken as L1P_T_REQ (which is accidently the first element and thus 0). This patch adds a new element to the enum that has the value 0 to detect uninitialized elements of the femtobts_sysprim_type array. Those will then show up in the log as 'SYS Prim XXX is not a Request!'. This patch also adds missing definitions of the CalibTbl messages in the femtobts_sysprim_type mapping so that the requests can still be identified as such. Sponsored-by: On-Waves ehf --- src/osmo-bts-sysmo/femtobts.c | 10 ++++++++++ src/osmo-bts-sysmo/femtobts.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c index 6bd9ce4..1e513bf 100644 --- a/src/osmo-bts-sysmo/femtobts.c +++ b/src/osmo-bts-sysmo/femtobts.c @@ -106,6 +106,16 @@ const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { [SuperFemto_PrimId_RfClockSetupCnf] = L1P_T_CONF, [SuperFemto_PrimId_Layer1ResetReq] = L1P_T_REQ, [SuperFemto_PrimId_Layer1ResetCnf] = L1P_T_CONF, +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(2,1,0) + [SuperFemto_PrimId_GetTxCalibTblReq] = L1P_T_REQ, + [SuperFemto_PrimId_GetTxCalibTblCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SetTxCalibTblReq] = L1P_T_REQ, + [SuperFemto_PrimId_SetTxCalibTblCnf] = L1P_T_CONF, + [SuperFemto_PrimId_GetRxCalibTblReq] = L1P_T_REQ, + [SuperFemto_PrimId_GetRxCalibTblCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SetRxCalibTblReq] = L1P_T_REQ, + [SuperFemto_PrimId_SetRxCalibTblCnf] = L1P_T_CONF, +#endif }; const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { diff --git a/src/osmo-bts-sysmo/femtobts.h b/src/osmo-bts-sysmo/femtobts.h index 7239757..a2b8dea 100644 --- a/src/osmo-bts-sysmo/femtobts.h +++ b/src/osmo-bts-sysmo/femtobts.h @@ -44,6 +44,7 @@ (OSMO_MAX(sizeof(SuperFemto_Prim_t), sizeof(GsmL1_Prim_t)) + 128) enum l1prim_type { + L1P_T_INVALID, /* this must be 0 to detect uninitialized elements */ L1P_T_REQ, L1P_T_CONF, L1P_T_IND, -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 4 13:56:10 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 14:56:10 +0100 Subject: [PATCH 2/4] femto: Add mappings for MuteRfReq/MuteRfCnf In-Reply-To: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> References: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1383573372-15482-2-git-send-email-jerlbeck@sysmocom.de> This add the mappings for SuperFemto_PrimId_MuteRfReq and SuperFemto_PrimId_MuteRfCnf to the arrays femtobts_sysprim_type, femtobts_sysprim_names, and femtobts_sysprim_req2conf. Sponsored-by: On-Waves ehf --- src/osmo-bts-sysmo/femtobts.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c index 1e513bf..28d861c 100644 --- a/src/osmo-bts-sysmo/femtobts.c +++ b/src/osmo-bts-sysmo/femtobts.c @@ -116,6 +116,10 @@ const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { [SuperFemto_PrimId_SetRxCalibTblReq] = L1P_T_REQ, [SuperFemto_PrimId_SetRxCalibTblCnf] = L1P_T_CONF, #endif +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0) + [SuperFemto_PrimId_MuteRfReq] = L1P_T_REQ, + [SuperFemto_PrimId_MuteRfCnf] = L1P_T_CONF, +#endif }; const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { @@ -143,6 +147,10 @@ const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { { SuperFemto_PrimId_SetRxCalibTblReq, "SET-RX-CALIB.req" }, { SuperFemto_PrimId_SetRxCalibTblCnf, "SET-RX-CALIB.cnf" }, #endif +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0) + { SuperFemto_PrimId_MuteRfReq, "MUTE-RF.req" }, + { SuperFemto_PrimId_MuteRfCnf, "MUTE-RF.cnf" }, +#endif { 0, NULL } }; @@ -159,6 +167,9 @@ const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { [SuperFemto_PrimId_GetRxCalibTblReq] = SuperFemto_PrimId_GetRxCalibTblCnf, [SuperFemto_PrimId_SetRxCalibTblReq] = SuperFemto_PrimId_SetRxCalibTblCnf, #endif +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0) + [SuperFemto_PrimId_MuteRfReq] = SuperFemto_PrimId_MuteRfCnf, +#endif }; const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 4 13:56:11 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 14:56:11 +0100 Subject: [PATCH 3/4] sysmobts: Add L1 support for the new RF mute request In-Reply-To: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> References: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1383573372-15482-3-git-send-email-jerlbeck@sysmocom.de> This adds a new function l1if_mute_rf(femtol1_hdl, ch_mute[8]) to set the mute state for each radio channel. On completion and iff l1if_mute_rf() returned 0 the callback oml_mo_rf_lock_chg(mo, ch_mute_state[8], success) is invoked when the response from the superfemto DSP is received. Ticket: OW#976 Sponsored-by: On-Waves ehf --- include/osmo-bts/oml.h | 4 ++++ src/osmo-bts-sysmo/l1_if.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.h | 3 +++ src/osmo-bts-sysmo/oml.c | 6 ++++++ 4 files changed, 61 insertions(+) diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 5e9c880..92695ca 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -17,6 +17,10 @@ int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state); /* First initialization of MO, does _not_ generate state changes */ void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state); +/* Update admin state and send ACK/NACK */ +int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8], + int success); + /* Transmit STATE CHG REP even if there was no state change */ int oml_tx_state_changed(struct gsm_abis_mo *mo); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3dbcd53..36df462 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1103,6 +1103,54 @@ int l1if_activate_rf(struct femtol1_hdl *hdl, int on) return l1if_req_compl(hdl, msg, activate_rf_compl_cb); } +static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + SuperFemto_Prim_t *sysp = msgb_sysprim(resp); + GsmL1_Status_t status; + + status = sysp->u.muteRfCnf.status; + + if (status != GsmL1_Status_Success) { + LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n", + get_value_string(femtobts_l1status_names, status)); + oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0); + } else { + LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", + get_value_string(femtobts_l1status_names, status)); + sysmobts_led_set(LED_RF_ACTIVE, !fl1h->last_rf_mute[0]); + oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); + } + + msgb_free(resp); + + return 0; +} + +/* mute/unmute RF time slots */ +int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8]) +{ + struct msgb *msg = sysp_msgb_alloc(); + SuperFemto_Prim_t *sysp = msgb_sysprim(msg); + + LOGP(DL1C, LOGL_INFO, "Tx RF-MUTE.req (%d, %d, %d, %d, %d, %d, %d, %d)\n", + mute[0], mute[1], mute[2], mute[3], + mute[4], mute[5], mute[6], mute[7] + ); + +#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(3,6,0) + LOGP(DL1C, LOGL_ERROR, "RF-MUTE.req not supported by SuperFemto\n"); + return -ENOTSUP; +#endif /* < 3.6.0 */ + + sysp->id = SuperFemto_PrimId_MuteRfReq; + memcpy(sysp->u.muteRfReq.u8Mute, mute, sizeof(sysp->u.muteRfReq.u8Mute)); + /* save for later use */ + memcpy(hdl->last_rf_mute, mute, sizeof(hdl->last_rf_mute)); + + return l1if_req_compl(hdl, msg, mute_rf_compl_cb); +} + /* call-back on arrival of DSP+FPGA version + band capability */ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) { diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 8d63569..d659841 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -76,6 +76,8 @@ struct femtol1_hdl { int fixup_needed; struct calib_send_state st; + + uint8_t last_rf_mute[8]; }; #define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) @@ -95,6 +97,7 @@ int l1if_reset(struct femtol1_hdl *hdl); int l1if_activate_rf(struct femtol1_hdl *hdl, int on); int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags); int l1if_set_txpower(struct femtol1_hdl *fl1h, float tx_power); +int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8]); struct msgb *l1p_msgb_alloc(void); struct msgb *sysp_msgb_alloc(void); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index c09b3f3..822453f 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -326,6 +326,12 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) return l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb); } +int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8], + int success) +{ + return 0; +} + static int ts_connect(struct gsm_bts_trx_ts *ts) { struct msgb *msg = l1p_msgb_alloc(); -- 1.7.9.5 From holger at freyther.de Tue Nov 5 14:44:46 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 5 Nov 2013 15:44:46 +0100 Subject: [PATCH 3/4] sysmobts: Add L1 support for the new RF mute request In-Reply-To: <1383573372-15482-3-git-send-email-jerlbeck@sysmocom.de> References: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> <1383573372-15482-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131105144446.GA5365@xiaoyu.lan> On Mon, Nov 04, 2013 at 02:56:11PM +0100, Jacob Erlbeck wrote: Thanks for the patch! Nice to have this implemented. Can you please send the diff for OpenBSC to add the flag for procedure pending? I added/changed the following guards for < 3.6.0 compilation. #if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0) > +static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) > +{ ... > +} #endif > +/* mute/unmute RF time slots */ > +int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8]) > +{ ... > +#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(3,6,0) > + LOGP(DL1C, LOGL_ERROR, "RF-MUTE.req not supported by SuperFemto\n"); > + return -ENOTSUP; > +#endif /* < 3.6.0 */ #else > + return l1if_req_compl(hdl, msg, mute_rf_compl_cb); #endif From jerlbeck at sysmocom.de Mon Nov 4 13:56:12 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 14:56:12 +0100 Subject: [PATCH 4/4] sysmobts: Do a RF mute when Radio Carrier is locked In-Reply-To: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> References: <1383573372-15482-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1383573372-15482-4-git-send-email-jerlbeck@sysmocom.de> Currently a Change Administrative State Request is just applied unconditionally to the object's state object and then acknowledged. This patch implements the special handling of setting the Radio Carriers state to LOCK or UNLOCK. This is done by passing the appropriate mute command to the L1 layer. Always all radio channels are affected, it is not possible to lock single radio channels. On success, an ACK is sent back to the bsc with the new state (based on the state passed in the callback by the L1 layer). If something went wrong or the firmware doesn't support RF mute, a NACK (REQ_NOT_GRANTED) is sent instead. Note that a NACK for such a request hasn't been sent by the BTS to the BSC yet, so (albeit it's spec conformant to do so) the BSC must be prepared to handle this correctly. Ticket: OW#976 Sponsored-by: On-Waves ehf --- include/osmo-bts/oml.h | 1 + src/common/oml.c | 5 ++++ src/osmo-bts-sysmo/oml.c | 70 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 92695ca..4281fd3 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -10,6 +10,7 @@ int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type); int oml_mo_opstart_ack(struct gsm_abis_mo *mo); int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause); int oml_mo_statechg_ack(struct gsm_abis_mo *mo); +int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause); /* Change the state and send STATE CHG REP */ int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state); diff --git a/src/common/oml.c b/src/common/oml.c index 1c38c66..bf174b5 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -299,6 +299,11 @@ int oml_mo_statechg_ack(struct gsm_abis_mo *mo) return oml_mo_send_msg(mo, msg, NM_MT_CHG_ADM_STATE_ACK); } +int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause) +{ + return oml_mo_fom_ack_nack(mo, NM_MT_CHG_ADM_STATE, nack_cause); +} + int oml_mo_opstart_ack(struct gsm_abis_mo *mo) { return oml_mo_fom_ack_nack(mo, NM_MT_OPSTART, 0); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 822453f..8e76093 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -326,10 +326,31 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) return l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb); } +static int trx_rf_lock(struct gsm_bts_trx *trx, int locked) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + uint8_t mute[8]; + int i; + + for (i = 0; i < ARRAY_SIZE(mute); ++i) + mute[i] = locked ? 1 : 0; + + return l1if_mute_rf(fl1h, mute); +} + int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8], int success) { - return 0; + if (success) { + /* assume mute_state[i] == mute_state[k] */ + mo->nm_state.administrative = + mute_state[0] ? NM_STATE_LOCKED : NM_STATE_UNLOCKED; + mo->procedure_pending = 0; + return oml_mo_statechg_ack(mo); + } else { + mo->procedure_pending = 0; + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } } static int ts_connect(struct gsm_bts_trx_ts *ts) @@ -1461,9 +1482,50 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state) { - /* blindly accept all state changes */ - mo->nm_state.administrative = adm_state; - return oml_mo_statechg_ack(mo); + int rc; + int granted = 0; + + switch (mo->obj_class) { + case NM_OC_RADIO_CARRIER: + + if (mo->procedure_pending) { + LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: " + "pending procedure on RC %d\n", + ((struct gsm_bts_trx *)obj)->nr); + return 0; + } + mo->procedure_pending = 1; + switch (adm_state) { + case NM_STATE_LOCKED: + rc = trx_rf_lock(obj, 1); + break; + case NM_STATE_UNLOCKED: + rc = trx_rf_lock(obj, 0); + break; + default: + granted = 1; + break; + } + + if (!granted && rc == 0) + /* in progress, will send ack/nack after completion */ + return 0; + + mo->procedure_pending = 0; + + break; + default: + /* blindly accept all state changes */ + granted = 1; + break; + } + + if (granted) { + mo->nm_state.administrative = adm_state; + return oml_mo_statechg_ack(mo); + } else + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) { -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 4 17:13:22 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 18:13:22 +0100 Subject: [PATCH] sysmobts: Do a RF mute when Radio Carrier is locked In-Reply-To: <1383573372-15482-4-git-send-email-jerlbeck@sysmocom.de> References: <1383573372-15482-4-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1383585202-18595-1-git-send-email-jerlbeck@sysmocom.de> Currently a Change Administrative State Request is just applied unconditionally to the object's state object and then acknowledged. This patch implements the special handling of setting the Radio Carriers state to LOCK or UNLOCK. This is done by passing the appropriate mute command to the L1 layer. Always all radio channels are affected, it is not possible to lock single radio channels. On success, an ACK is sent back to the bsc with the new state (based on the state passed in the callback by the L1 layer). If something went wrong or the firmware doesn't support RF mute, a NACK (REQ_NOT_GRANTED) is sent instead. Note that a NACK for such a request hasn't been sent by the BTS to the BSC yet, so (albeit it's spec conformant to do so) the BSC must be prepared to handle this correctly. Ticket: OW#976 Sponsored-by: On-Waves ehf --- include/osmo-bts/oml.h | 1 + src/common/oml.c | 5 ++++ src/osmo-bts-sysmo/oml.c | 70 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 92695ca..4281fd3 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -10,6 +10,7 @@ int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type); int oml_mo_opstart_ack(struct gsm_abis_mo *mo); int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause); int oml_mo_statechg_ack(struct gsm_abis_mo *mo); +int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause); /* Change the state and send STATE CHG REP */ int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state); diff --git a/src/common/oml.c b/src/common/oml.c index 1c38c66..bf174b5 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -299,6 +299,11 @@ int oml_mo_statechg_ack(struct gsm_abis_mo *mo) return oml_mo_send_msg(mo, msg, NM_MT_CHG_ADM_STATE_ACK); } +int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause) +{ + return oml_mo_fom_ack_nack(mo, NM_MT_CHG_ADM_STATE, nack_cause); +} + int oml_mo_opstart_ack(struct gsm_abis_mo *mo) { return oml_mo_fom_ack_nack(mo, NM_MT_OPSTART, 0); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 822453f..c87acb6 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -326,10 +326,31 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) return l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb); } +static int trx_rf_lock(struct gsm_bts_trx *trx, int locked) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + uint8_t mute[8]; + int i; + + for (i = 0; i < ARRAY_SIZE(mute); ++i) + mute[i] = locked ? 1 : 0; + + return l1if_mute_rf(fl1h, mute); +} + int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8], int success) { - return 0; + if (success) { + /* assume mute_state[i] == mute_state[k] */ + mo->nm_state.administrative = + mute_state[0] ? NM_STATE_LOCKED : NM_STATE_UNLOCKED; + mo->procedure_pending = 0; + return oml_mo_statechg_ack(mo); + } else { + mo->procedure_pending = 0; + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } } static int ts_connect(struct gsm_bts_trx_ts *ts) @@ -1461,9 +1482,50 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state) { - /* blindly accept all state changes */ - mo->nm_state.administrative = adm_state; - return oml_mo_statechg_ack(mo); + int rc = -EINVAL; + int granted = 0; + + switch (mo->obj_class) { + case NM_OC_RADIO_CARRIER: + + if (mo->procedure_pending) { + LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: " + "pending procedure on RC %d\n", + ((struct gsm_bts_trx *)obj)->nr); + return 0; + } + mo->procedure_pending = 1; + switch (adm_state) { + case NM_STATE_LOCKED: + rc = trx_rf_lock(obj, 1); + break; + case NM_STATE_UNLOCKED: + rc = trx_rf_lock(obj, 0); + break; + default: + granted = 1; + break; + } + + if (!granted && rc == 0) + /* in progress, will send ack/nack after completion */ + return 0; + + mo->procedure_pending = 0; + + break; + default: + /* blindly accept all state changes */ + granted = 1; + break; + } + + if (granted) { + mo->nm_state.administrative = adm_state; + return oml_mo_statechg_ack(mo); + } else + return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT); + } int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) { -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 4 17:13:52 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 4 Nov 2013 18:13:52 +0100 Subject: [PATCH] sysmobts: Use status flags instead of direct LED access Message-ID: <1383585232-18635-1-git-send-email-jerlbeck@sysmocom.de> Currently the LEDs are being accessed directly from within the l1_if.c file. So the handling of rf mute and activate/deactivate both access LED_RF_ACTIVE directly. This may lead to an inconsistent LED status. This patch replaces these calls to sysmobts_led_set() by an abstract equivalent bts_update_status(), that uses a set of independant status ids. The associated values can than be combined into a visible LED status. Currently LED_RF_ACTIVE is on iff BTS_STATUS_RF_ACTIVE is set and BTS_STATUS_RF_MUTE is not set. Sponsored-by: On-Waves ehf --- include/osmo-bts/bts.h | 7 +++++++ src/osmo-bts-sysmo/l1_if.c | 6 +++--- src/osmo-bts-sysmo/main.c | 25 +++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 583c1eb..503dcb0 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -3,6 +3,11 @@ #include +enum bts_global_status { + BTS_STATUS_RF_ACTIVE, + BTS_STATUS_RF_MUTE, +}; + extern void *tall_bts_ctx; int bts_init(struct gsm_bts *bts); @@ -27,5 +32,7 @@ int lchan_init_lapdm(struct gsm_lchan *lchan); void load_timer_start(struct gsm_bts *bts); +void bts_update_status(enum bts_global_status which, int on); + #endif /* _BTS_H */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 36df462..71920ac 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1021,7 +1021,7 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) get_value_string(femtobts_l1status_names, status)); bts_shutdown(trx->bts, "RF-ACT failure"); } else - sysmobts_led_set(LED_RF_ACTIVE, 1); + bts_update_status(BTS_STATUS_RF_ACTIVE, 1); /* signal availability */ oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK); @@ -1032,7 +1032,7 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) for (i = 0; i < ARRAY_SIZE(trx->ts); i++) oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); } else { - sysmobts_led_set(LED_RF_ACTIVE, 0); + bts_update_status(BTS_STATUS_RF_ACTIVE, 0); oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); } @@ -1118,7 +1118,7 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) } else { LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", get_value_string(femtobts_l1status_names, status)); - sysmobts_led_set(LED_RF_ACTIVE, !fl1h->last_rf_mute[0]); + bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); } diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 5a7c812..046326b 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -51,6 +51,7 @@ #include "utils.h" #include "eeprom.h" #include "l1_if.h" +#include "hw_misc.h" /* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -122,6 +123,30 @@ void clk_cal_use_eeprom(struct gsm_bts *bts) "Read clock calibration(%d) from EEPROM.\n", hdl->clk_cal); } +void bts_update_status(enum bts_global_status which, int on) +{ + static uint64_t states = 0; + uint64_t old_states = states; + int led_rf_active_on; + + if (on) + states |= (1ULL << which); + else + states &= ~(1ULL << which); + + led_rf_active_on = + (states & (1ULL << BTS_STATUS_RF_ACTIVE)) && + !(states & (1ULL << BTS_STATUS_RF_MUTE)); + + LOGP(DL1C, LOGL_INFO, + "Set global status #%d to %d (%04llx -> %04llx), LEDs: ACT %d\n", + which, on, + (long long)old_states, (long long)states, + led_rf_active_on); + + sysmobts_led_set(LED_RF_ACTIVE, led_rf_active_on); +} + static void print_help() { printf( "Some useful options:\n" -- 1.7.9.5 From ml at mail.tsaitgaist.info Mon Nov 4 22:01:22 2013 From: ml at mail.tsaitgaist.info (Kevin Redon) Date: Mon, 04 Nov 2013 23:01:22 +0100 Subject: fix subscriber not seen as authorized Message-ID: <1383602245-sup-2025@dennou> here a small patch for a bug which prevent phones to register. more info is available in the patch note: the same mistake may exist at other places. I only looked at how the users are read kevin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-fix-database-get-value-type.patch Type: application/octet-stream Size: 1443 bytes Desc: not available URL: From jerlbeck at sysmocom.de Tue Nov 5 12:42:59 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Nov 2013 13:42:59 +0100 Subject: [PATCH 1/2] sysmobts: Only set RC state to LOCK if all channels are muted Message-ID: <1383655380-24879-1-git-send-email-jerlbeck@sysmocom.de> Currently only mute_state[0] (refers to ts[0]) is inspected to determine, whether the Radio Carrier's state is set to LOCK. This patch changes this by looking at all channels and using LOCK if (and only if) all channels have been muted successfully. Sponsored-by: On-Waves ehf --- src/osmo-bts-sysmo/oml.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index c87acb6..4c63fd5 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -342,9 +342,15 @@ int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8], int success) { if (success) { - /* assume mute_state[i] == mute_state[k] */ + int i; + int is_locked = 1; + + for (i = 0; i < ARRAY_SIZE(mute_state); ++i) + if (!mute_state[i]) + is_locked = 0; + mo->nm_state.administrative = - mute_state[0] ? NM_STATE_LOCKED : NM_STATE_UNLOCKED; + is_locked ? NM_STATE_LOCKED : NM_STATE_UNLOCKED; mo->procedure_pending = 0; return oml_mo_statechg_ack(mo); } else { -- 1.7.9.5 From jerlbeck at sysmocom.de Tue Nov 5 12:43:00 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 5 Nov 2013 13:43:00 +0100 Subject: [PATCH 2/2] sysmobts: Notify the BTS about all muted lchans In-Reply-To: <1383655380-24879-1-git-send-email-jerlbeck@sysmocom.de> References: <1383655380-24879-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1383655380-24879-2-git-send-email-jerlbeck@sysmocom.de> Currently it takes some time (around 30s) until it is detected that the radio link is down after mute. Not till then the BSC is informed and the call terminated. This patch modifies this behaviour by sending a RSL_MT_CONN_FAIL message with cause RSL_ERR_RADIO_LINK_FAIL for each muted and active lchan immediately after the corresponding Change Administrative State Request has been acknowledged. Ticket: OW#976 Sponsored-by: On-Waves ehf --- src/osmo-bts-sysmo/l1_if.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 71920ac..de8c239 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1103,6 +1103,27 @@ int l1if_activate_rf(struct femtol1_hdl *hdl, int on) return l1if_req_compl(hdl, msg, activate_rf_compl_cb); } +static void mute_handle_ts(struct gsm_bts_trx_ts *ts, int is_muted) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) { + struct gsm_lchan *lchan = &ts->lchan[i]; + + if (!is_muted) + continue; + + if (lchan->state != LCHAN_S_ACTIVE) + continue; + + if (lchan->s <= 0) + continue; + + lchan->s = 0; + rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL); + } +} + static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) { struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); @@ -1116,10 +1137,19 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp) get_value_string(femtobts_l1status_names, status)); oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0); } else { + int i; + LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", get_value_string(femtobts_l1status_names, status)); bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); + + osmo_static_assert( + ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute), + ts_array_size); + + for (i = 0; i < ARRAY_SIZE(fl1h->last_rf_mute); ++i) + mute_handle_ts(&trx->ts[i], fl1h->last_rf_mute[i]); } msgb_free(resp); -- 1.7.9.5 From holger at freyther.de Tue Nov 5 15:09:40 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 5 Nov 2013 16:09:40 +0100 Subject: [PATCH 2/2] sysmobts: Notify the BTS about all muted lchans In-Reply-To: <1383655380-24879-2-git-send-email-jerlbeck@sysmocom.de> References: <1383655380-24879-1-git-send-email-jerlbeck@sysmocom.de> <1383655380-24879-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131105150940.GB5365@xiaoyu.lan> On Tue, Nov 05, 2013 at 01:43:00PM +0100, Jacob Erlbeck wrote: Great. I only changed the subject to "BSC" and applied the patch by hand because of my previous addition of #ifdef. So please check that I have done it correctly. thanks holger PS: I am adding procedure_pending by hand. We can replace it with your patch tomorrow. > From laforge at gnumonks.org Tue Nov 5 15:58:25 2013 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 5 Nov 2013 16:58:25 +0100 Subject: OsmoDevCon 2014 / Date / Venue Message-ID: <20131105155825.GK12353@nataraja.gnumonks.org> Hi all, time is moving fast, and I want to start some initial discussion and planning for OsmoDevCon 2014. There are basically four questions which I'm raising below. Please provide your feedback to the osmocom-event-orga mailing list only, to avoid cross-posting over all the project lists. = Who? = My intention is to keep it an 'active developer/contributer only' event, like we had it before. I would also want to keep the group relatively small, to keep the 'Osmocom family' atmosphere. If desired, we could have one half or full day of public prsentations in a larger auditorium, but the developer meeting should be a close group, as known so far. = Where? = If we keep the number of attendees within the same range as this year, then I'm sure we could again hold it at the same venue. I know it is not perfect, but it is a place that we have access to, 24 hours per day, and free of cost for community projects like osmocom.org. If the community wants a larger event, then this is something that would require more funds and much more time organizing. And that is something that I personally could not offer to take care of, sorry. I'm happy to attend and support any larger events, but I'm unable to take care of fundraising and venue research. = When? = Q1/2014. In January, I'm not aware of any 'blocker' events. February, there is Fosdem (Feb 1 + Feb 2), and MWC from Feb 24 through Feb 27. In March there is CeBIT (March 10-14) and Easter holidays (with EasterHegg March 17-21). Did I miss any other FOSS / mobile event that might clash in Q1? So my preference woudl be to do it either late January (23-26) or in February (6-9 or 13-16). Any preferences regarding preferred schedule? Once we have some concencus here on the list [and we want to do it in the same size / venue], I'll talk to IN-Berlin. = What? = I think that question is easy to answer, if we have the above three figured out... There's no shortage of topics, I suppose. You can start adding your suggestions to http://openbsc.osmocom.org/trac/wiki/OsmoDevCon2014 Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 190 bytes Desc: Digital signature URL: From lnve at s21sec.com Wed Nov 6 23:46:15 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Thu, 7 Nov 2013 00:46:15 +0100 Subject: OPENBSC/LCR/Asterisk Message-ID: <57BA75DC-8FFA-47BA-A584-382070B726EF@s21sec.com> Hi, I have installed an infrastructure IPACCESS - OpenBSC - LCR (without misdn) - Asterisk LCR si connected via SIP to Asterisk. The problem is that i can call MT <-> softphone, soft and MT <-> MT BUT i don't hear anything in any side ( softphone <-> softphone works well). I think is a codec problem: Configured TCH/F FR for MT and we tried different codecs (alaw,gsm,ulaw, etc etc). Also I tried bridging GSM and SIP interfaces on LCR config and putting rtp-bridge. On LCR debug I see this error: 000000 DEBUG (in port.cpp/new_state() line 267): PORT(SIP-0-out) new state PORT_STATE_OUT_ALERTING --> PORT_STATE_CONNECT nua: nua_application_event: entering 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack received (handle=0x94906d8) 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received nua: nua_application_event: entering 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack received (handle=0x94906d8) 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received nua: nua_application_event: entering 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 5 from stack received (handle=0x94906d8) 000000 DEBUG (in sip.cpp/sip_callback() line 1837): active received 000000 TRACE 06.11.13 20:10:06.434 EP(2): CONNECT from CH(2) connect id number= present='not available' 000000 TRACE 06.11.13 20:10:06.435 EP(1): CONNECT to CH(1) connect id number= present='not available' 000000 TRACE 06.11.13 20:10:06.435 EP(1): TONE to CH(1) off 000000 TRACE 06.11.13 20:10:06.436 CH(1): MNCC_SETUP_RSP LCR<->BSC connected type=0 plan=1 present=0 screen=3 number= 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_IN_ALERTING --> PORT_STATE_CONNECT_WAITING 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting tone '' dir '' 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 TRACE 06.11.13 20:10:06.563 CH(1): MNCC_SETUP_COMPL_IND LCR<->BSC 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_CONNECT_WAITING --> PORT_STATE_CONNECT 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. <--...--> <-- THIS ERROR REPEATED CONTINUOUSLY DURING THE CALL --> <--...--> Configurations: OpenBSC trx 0 config: trx 0 rf_locked 0 arfcn 636 nominal power 23 max_power_red 0 rsl e1 tei 0 timeslot 0 phys_chan_config CCCH+SDCCH4 hopping enabled 0 timeslot 1 phys_chan_config SDCCH8 hopping enabled 0 timeslot 2 phys_chan_config TCH/F hopping enabled 0 timeslot 3 phys_chan_config TCH/F hopping enabled 0 timeslot 4 phys_chan_config TCH/F hopping enabled 0 timeslot 5 phys_chan_config TCH/F hopping enabled 0 timeslot 6 phys_chan_config TCH/F hopping enabled 0 timeslot 7 phys_chan_config TCH/F hopping enabled 0 mncc-int default-codec tch-f fr LCR config: interfaces.conf [GSM] gsm-bs tones yes earlyb no [SIP] extern sip localhost:5059 localhost:5060 tones yes earlyb yes Asterisk User conf: user.conf (one user) [6001] fullname = SIPPhone2 registersip = no host = dynamic callgroup = 1 mailbox = 6001 call-limit = 100 type = peer username = 6001 secret = nomypasshere transfer = yes nat = yes context = openBSC_Integration dtmfmode = rfc2833 cid_number = 6001 disallow = all allow = alaw,gsm ; I Tried different codecs callcounter = no hasvoicemail = no vmsecret = email = threewaycalling = no hasdirectory = no callwaiting = no hasmanager = no hasagent = no hassip = yes hasiax = no canreinvite = no insecure = no pickupgroup = 1 autoprov = yes label = 6001 linenumber = 1 LINEKEYS = 1 Other configs seem irrelevant... -- -- Leonardo Nve Project Manager ACSS Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Sun Nov 10 18:59:41 2013 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 10 Nov 2013 22:59:41 +0400 Subject: OPENBSC/LCR/Asterisk In-Reply-To: <57BA75DC-8FFA-47BA-A584-382070B726EF@s21sec.com> References: <57BA75DC-8FFA-47BA-A584-382070B726EF@s21sec.com> Message-ID: Leonardo, Look into the Wireshark capture of SIP traffic - which codecs are offered and how does the codec negotiation goes. On Thu, Nov 7, 2013 at 3:46 AM, Leonardo Nve wrote: > Hi, > > I have installed an infrastructure IPACCESS - OpenBSC - LCR (without misdn) > - Asterisk > > LCR si connected via SIP to Asterisk. > > > The problem is that i can call MT <-> softphone, soft and MT <-> MT BUT i > don't hear anything in any side ( softphone <-> softphone works well). I > think is a codec problem: > > Configured TCH/F FR for MT and we tried different codecs (alaw,gsm,ulaw, etc > etc). > Also I tried bridging GSM and SIP interfaces on LCR config and putting > rtp-bridge. > > On LCR debug I see this error: > > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(SIP-0-out) new state > PORT_STATE_OUT_ALERTING --> PORT_STATE_CONNECT > nua: nua_application_event: entering > 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack > received (handle=0x94906d8) > 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received > nua: nua_application_event: entering > 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack > received (handle=0x94906d8) > 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received > nua: nua_application_event: entering > 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 5 from stack > received (handle=0x94906d8) > 000000 DEBUG (in sip.cpp/sip_callback() line 1837): active received > 000000 TRACE 06.11.13 20:10:06.434 EP(2): CONNECT from CH(2) connect id > number= present='not available' > 000000 TRACE 06.11.13 20:10:06.435 EP(1): CONNECT to CH(1) connect id > number= present='not available' > 000000 TRACE 06.11.13 20:10:06.435 EP(1): TONE to CH(1) off > 000000 TRACE 06.11.13 20:10:06.436 CH(1): MNCC_SETUP_RSP LCR<->BSC > connected type=0 plan=1 present=0 screen=3 number= > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state > PORT_STATE_IN_ALERTING --> PORT_STATE_CONNECT_WAITING > 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting > tone '' dir '' > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 TRACE 06.11.13 20:10:06.563 CH(1): MNCC_SETUP_COMPL_IND LCR<->BSC > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state > PORT_STATE_CONNECT_WAITING --> PORT_STATE_CONNECT > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. > <--...--> > <-- THIS ERROR REPEATED CONTINUOUSLY DURING THE CALL --> > <--...--> > > Configurations: > > OpenBSC trx 0 config: > > trx 0 > rf_locked 0 > arfcn 636 > nominal power 23 > max_power_red 0 > rsl e1 tei 0 > timeslot 0 > phys_chan_config CCCH+SDCCH4 > hopping enabled 0 > timeslot 1 > phys_chan_config SDCCH8 > hopping enabled 0 > timeslot 2 > phys_chan_config TCH/F > hopping enabled 0 > timeslot 3 > phys_chan_config TCH/F > hopping enabled 0 > timeslot 4 > phys_chan_config TCH/F > hopping enabled 0 > timeslot 5 > phys_chan_config TCH/F > hopping enabled 0 > timeslot 6 > phys_chan_config TCH/F > hopping enabled 0 > timeslot 7 > phys_chan_config TCH/F > hopping enabled 0 > mncc-int > default-codec tch-f fr > > LCR config: > > > interfaces.conf > > [GSM] > gsm-bs > tones yes > earlyb no > > [SIP] > extern > sip localhost:5059 localhost:5060 > tones yes > earlyb yes > > Asterisk User conf: > > user.conf (one user) > > [6001] > fullname = SIPPhone2 > registersip = no > host = dynamic > callgroup = 1 > mailbox = 6001 > call-limit = 100 > type = peer > username = 6001 > secret = nomypasshere > transfer = yes > nat = yes > context = openBSC_Integration > dtmfmode = rfc2833 > cid_number = 6001 > disallow = all > allow = alaw,gsm ; I Tried different codecs > > callcounter = no > hasvoicemail = no > vmsecret = > email = > threewaycalling = no > hasdirectory = no > callwaiting = no > hasmanager = no > hasagent = no > hassip = yes > hasiax = no > canreinvite = no > insecure = no > pickupgroup = 1 > autoprov = yes > label = 6001 > linenumber = 1 > LINEKEYS = 1 > > > Other configs seem irrelevant... > > > > -- > -- > Leonardo Nve > Project Manager ACSS > Grupo S21sec Gesti?n, S.A. > Telefono 628275870 > -- > > La informaci?n contenida en este mail, as? como los archivos adjuntos,es > CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las > medidas necesarias para asegurar el tratamiento confidencial de los datos > de car?cter personal. En el caso de que el destinatario del correo > no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya > de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la > situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la > empresa remitente realizar acciones legales de diferente envergadura. > > > > > -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From lnve at s21sec.com Sun Nov 10 21:20:27 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Sun, 10 Nov 2013 22:20:27 +0100 Subject: OPENBSC/LCR/Asterisk In-Reply-To: References: <57BA75DC-8FFA-47BA-A584-382070B726EF@s21sec.com> Message-ID: Thanks Alexander, I reinstalled all from scratch and now it's working with chan_lcr and sip connection between LCR and Asterisk. The error was that the opencore-amr libraries were installed before LCR make. Leonardo. El 10/11/2013, a las 19:59, Alexander Chemeris escribi?: > Leonardo, > > Look into the Wireshark capture of SIP traffic - which codecs are > offered and how does the codec negotiation goes. > > On Thu, Nov 7, 2013 at 3:46 AM, Leonardo Nve wrote: >> Hi, >> >> I have installed an infrastructure IPACCESS - OpenBSC - LCR (without misdn) >> - Asterisk >> >> LCR si connected via SIP to Asterisk. >> >> >> The problem is that i can call MT <-> softphone, soft and MT <-> MT BUT i >> don't hear anything in any side ( softphone <-> softphone works well). I >> think is a codec problem: >> >> Configured TCH/F FR for MT and we tried different codecs (alaw,gsm,ulaw, etc >> etc). >> Also I tried bridging GSM and SIP interfaces on LCR config and putting >> rtp-bridge. >> >> On LCR debug I see this error: >> >> 000000 DEBUG (in port.cpp/new_state() line 267): PORT(SIP-0-out) new state >> PORT_STATE_OUT_ALERTING --> PORT_STATE_CONNECT >> nua: nua_application_event: entering >> 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack >> received (handle=0x94906d8) >> 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received >> nua: nua_application_event: entering >> 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 7 from stack >> received (handle=0x94906d8) >> 000000 DEBUG (in sip.cpp/sip_callback() line 1825): state change received >> nua: nua_application_event: entering >> 000000 DEBUG (in sip.cpp/sip_callback() line 1775): Event 5 from stack >> received (handle=0x94906d8) >> 000000 DEBUG (in sip.cpp/sip_callback() line 1837): active received >> 000000 TRACE 06.11.13 20:10:06.434 EP(2): CONNECT from CH(2) connect id >> number= present='not available' >> 000000 TRACE 06.11.13 20:10:06.435 EP(1): CONNECT to CH(1) connect id >> number= present='not available' >> 000000 TRACE 06.11.13 20:10:06.435 EP(1): TONE to CH(1) off >> 000000 TRACE 06.11.13 20:10:06.436 CH(1): MNCC_SETUP_RSP LCR<->BSC >> connected type=0 plan=1 present=0 screen=3 number= >> 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state >> PORT_STATE_IN_ALERTING --> PORT_STATE_CONNECT_WAITING >> 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting >> tone '' dir '' >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 TRACE 06.11.13 20:10:06.563 CH(1): MNCC_SETUP_COMPL_IND LCR<->BSC >> 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state >> PORT_STATE_CONNECT_WAITING --> PORT_STATE_CONNECT >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> 000000 DEBUG (in gsm.cpp/audio_send() line 487): no valid CMR yet. >> <--...--> >> <-- THIS ERROR REPEATED CONTINUOUSLY DURING THE CALL --> >> <--...--> >> >> Configurations: >> >> OpenBSC trx 0 config: >> >> trx 0 >> rf_locked 0 >> arfcn 636 >> nominal power 23 >> max_power_red 0 >> rsl e1 tei 0 >> timeslot 0 >> phys_chan_config CCCH+SDCCH4 >> hopping enabled 0 >> timeslot 1 >> phys_chan_config SDCCH8 >> hopping enabled 0 >> timeslot 2 >> phys_chan_config TCH/F >> hopping enabled 0 >> timeslot 3 >> phys_chan_config TCH/F >> hopping enabled 0 >> timeslot 4 >> phys_chan_config TCH/F >> hopping enabled 0 >> timeslot 5 >> phys_chan_config TCH/F >> hopping enabled 0 >> timeslot 6 >> phys_chan_config TCH/F >> hopping enabled 0 >> timeslot 7 >> phys_chan_config TCH/F >> hopping enabled 0 >> mncc-int >> default-codec tch-f fr >> >> LCR config: >> >> >> interfaces.conf >> >> [GSM] >> gsm-bs >> tones yes >> earlyb no >> >> [SIP] >> extern >> sip localhost:5059 localhost:5060 >> tones yes >> earlyb yes >> >> Asterisk User conf: >> >> user.conf (one user) >> >> [6001] >> fullname = SIPPhone2 >> registersip = no >> host = dynamic >> callgroup = 1 >> mailbox = 6001 >> call-limit = 100 >> type = peer >> username = 6001 >> secret = nomypasshere >> transfer = yes >> nat = yes >> context = openBSC_Integration >> dtmfmode = rfc2833 >> cid_number = 6001 >> disallow = all >> allow = alaw,gsm ; I Tried different codecs >> >> callcounter = no >> hasvoicemail = no >> vmsecret = >> email = >> threewaycalling = no >> hasdirectory = no >> callwaiting = no >> hasmanager = no >> hasagent = no >> hassip = yes >> hasiax = no >> canreinvite = no >> insecure = no >> pickupgroup = 1 >> autoprov = yes >> label = 6001 >> linenumber = 1 >> LINEKEYS = 1 >> >> >> Other configs seem irrelevant... >> >> >> >> -- >> -- >> Leonardo Nve >> Project Manager ACSS >> Grupo S21sec Gesti?n, S.A. >> Telefono 628275870 >> -- >> >> La informaci?n contenida en este mail, as? como los archivos adjuntos,es >> CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las >> medidas necesarias para asegurar el tratamiento confidencial de los datos >> de car?cter personal. En el caso de que el destinatario del correo >> no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya >> de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la >> situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la >> empresa remitente realizar acciones legales de diferente envergadura. >> >> >> >> >> > > > > -- > Regards, > Alexander Chemeris. > CEO, Fairwaves LLC / ??? ??????? > http://fairwaves.ru > -- -- Leonardo Nve Project Manager ACSS Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. From jerlbeck at sysmocom.de Fri Nov 8 13:06:11 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 8 Nov 2013 14:06:11 +0100 Subject: [PATCH] nitb: Set the DST field in generated MM info messages Message-ID: <1383915971-21478-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. 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 3cfc455..0d1ba7b 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -656,6 +656,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; @@ -749,6 +750,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 */ @@ -768,8 +772,19 @@ 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; } +#ifdef GSM48_IE_NET_DST + ptr8 = msgb_put(msg, 3); + ptr8[0] = GSM48_IE_NET_DST; + ptr8[1] = 1; + ptr8[2] = dst; +#endif + DEBUGP(DMM, "-> MM INFO\n"); return gsm48_conn_sendmsg(msg, conn, NULL); -- 1.7.9.5 From holger at freyther.de Sat Nov 9 07:44:05 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 9 Nov 2013 08:44:05 +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: <20131109074405.GO16696@xiaoyu.lan> On Fri, Nov 08, 2013 at 02:06:11PM +0100, Jacob Erlbeck wrote: > 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. > + > + /* Does not support DST +2 */ > + if (local_time->tm_isdst) > + dst = 1; I think this code and the above message do not agree with each other? Or is "configured" to be read in the broad sense that DST is currently used on the host system? > +#ifdef GSM48_IE_NET_DST we depend on 0.6.4. You don't need these anymore. holger From jerlbeck at sysmocom.de Mon Nov 11 08:43:05 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 11 Nov 2013 09:43:05 +0100 Subject: [PATCH 1/2] gprs: Fix VTY NSVC initialisation bug by changing gprs_nsvc_create() Message-ID: <1384159386-19148-1-git-send-email-jerlbeck@sysmocom.de> Currently the field nsvci_is_valid is set to 0 in the NSVC object returned by gprs_nsvc_create(). This was a semantic change probably introduced by commit 5e6d679d. As a result, NSVC created via the VTY have this flag set to 0 causing RESET_ACK messages to be rejected. This patch changes the default behaviour of gprs_nsvc_create() to always set this flag. So it must be set to 0 explicitely if needed which is more intuitive and thus less error prone. It fixes breaking connections from the Gbproxy to the SGSN. Ticket: OW#874 Sponsored-by: On-Waves ehf --- src/gb/gprs_ns.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 55535ad..b500d9a 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -200,6 +200,7 @@ struct gprs_nsvc *gprs_nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci) nsvc = talloc_zero(nsi, struct gprs_nsvc); nsvc->nsvci = nsvci; + nsvc->nsvci_is_valid = 1; /* before RESET procedure: BLOCKED and DEAD */ nsvc->state = NSE_S_BLOCKED; nsvc->nsi = nsi; @@ -794,7 +795,6 @@ static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg) gprs_ns_ll_str(*nsvc)); orig_nsvc = *nsvc; *nsvc = gprs_nsvc_create((*nsvc)->nsi, nsvci); - (*nsvc)->nsvci_is_valid = 1; (*nsvc)->nsei = nsei; } } @@ -1193,6 +1193,7 @@ int gprs_ns_vc_create(struct gprs_ns_inst *nsi, struct msgb *msg, existing_nsvc = gprs_nsvc_by_nsvci(nsi, nsvci); if (!existing_nsvc) { *new_nsvc = gprs_nsvc_create(nsi, 0xffff); + (*new_nsvc)->nsvci_is_valid = 0; log_set_context(GPRS_CTX_NSVC, *new_nsvc); gprs_ns_ll_copy(*new_nsvc, fallback_nsvc); LOGP(DNS, LOGL_INFO, "Creating NS-VC for BSS at %s\n", @@ -1327,6 +1328,7 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx) /* Create the dummy NSVC that we use for sending * messages to non-existant/unknown NS-VC's */ nsi->unknown_nsvc = gprs_nsvc_create(nsi, 0xfffe); + nsi->unknown_nsvc->nsvci_is_valid = 0; llist_del(&nsi->unknown_nsvc->list); return nsi; @@ -1527,8 +1529,6 @@ struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi, nsvc = gprs_nsvc_create(nsi, nsvci); nsvc->ip.bts_addr = *dest; nsvc->nsei = nsei; - nsvc->nsvci = nsvci; - nsvc->nsvci_is_valid = 1; nsvc->remote_end_is_sgsn = 1; gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION); -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 11 08:43:06 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 11 Nov 2013 09:43:06 +0100 Subject: [PATCH 2/2] debian: Update the changelog In-Reply-To: <1384159386-19148-1-git-send-email-jerlbeck@sysmocom.de> References: <1384159386-19148-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1384159386-19148-2-git-send-email-jerlbeck@sysmocom.de> Sponsored-by: On-Waves ehf --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index d9870ba..e1102e1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libosmocore (0.6.4+git3) UNRELEASED; urgency=low + + * GPRS fix NS connections to a SGSN when configured via VTY + + -- Jacob Erlbeck Thu, 07 Nov 2013 16:07:20 +0100 + libosmocore (0.6.4+git2) UNRELEASED; urgency=low * GPRS related changes, some GSM encoding/decoding changes -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 11 13:13:12 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 11 Nov 2013 14:13:12 +0100 Subject: [PATCH 1/3] vty: Use new vty_install_default() function Message-ID: <1384175594-4925-1-git-send-email-jerlbeck@sysmocom.de> This patch removes the local 'end' and 'exit' implementations and uses the generic ones provided by libosmocore instead, which are enabled automatically when vty_install_default() is used. --- src/e1_input_vty.c | 2 ++ src/ipa_proxy.c | 26 +------------------------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index b6e1438..faaebd8 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -276,6 +276,8 @@ int e1inp_vty_init(void) { install_element(CONFIG_NODE, &cfg_e1inp_cmd); install_node(&e1inp_node, e1inp_config_write); + + vty_install_default(L_E1INP_NODE); 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); diff --git a/src/ipa_proxy.c b/src/ipa_proxy.c index 74cf427..a394b8c 100644 --- a/src/ipa_proxy.c +++ b/src/ipa_proxy.c @@ -644,28 +644,6 @@ static int ipa_cfg_write(struct vty *vty) return CMD_SUCCESS; } -DEFUN(ournode_exit, - ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n") -{ - switch (vty->node) { - case L_IPA_NODE: - vty->node = CONFIG_NODE; - vty->index = NULL; - break; - } - return CMD_SUCCESS; -} - -DEFUN(ournode_end, - ournode_end_cmd, "end", "End current mode and change to enable mode.\n") -{ - switch (vty->node) { - case L_IPA_NODE: - break; - } - return CMD_SUCCESS; -} - void ipa_proxy_vty_init(void) { tall_ipa_proxy_ctx = @@ -681,9 +659,7 @@ void ipa_proxy_vty_init(void) install_element(CONFIG_NODE, &ipa_cfg_cmd); install_node(&ipa_node, ipa_cfg_write); - install_default(L_IPA_NODE); - install_element(L_IPA_NODE, &ournode_exit_cmd); - install_element(L_IPA_NODE, &ournode_end_cmd); + vty_install_default(L_IPA_NODE); install_element(L_IPA_NODE, &ipa_instance_cfg_add_cmd); install_element(L_IPA_NODE, &ipa_route_cfg_add_cmd); } -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 11 13:13:13 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 11 Nov 2013 14:13:13 +0100 Subject: [PATCH 2/3] vty: Use same prompt string format like in libosmocore In-Reply-To: <1384175594-4925-1-git-send-email-jerlbeck@sysmocom.de> References: <1384175594-4925-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1384175594-4925-2-git-send-email-jerlbeck@sysmocom.de> Ensures a single blank after the '#'. Use (config-foo) instead (foo) for config nodes. --- src/e1_input_vty.c | 2 +- src/ipa_proxy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index faaebd8..d99c853 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -268,7 +268,7 @@ DEFUN(show_e1ts, struct cmd_node e1inp_node = { L_E1INP_NODE, - "%s(e1_input)#", + "%s(config-e1_input)# ", 1, }; diff --git a/src/ipa_proxy.c b/src/ipa_proxy.c index a394b8c..30840ef 100644 --- a/src/ipa_proxy.c +++ b/src/ipa_proxy.c @@ -612,7 +612,7 @@ DEFUN(ipa_instance_cfg_add, ipa_instance_cfg_add_cmd, struct cmd_node ipa_node = { L_IPA_NODE, - "%s(ipa)#", + "%s(config-ipa)# ", 1, }; -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 11 13:13:14 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 11 Nov 2013 14:13:14 +0100 Subject: [PATCH 3/3] ipa-proxy/vty: Removed enable/ipa node In-Reply-To: <1384175594-4925-1-git-send-email-jerlbeck@sysmocom.de> References: <1384175594-4925-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1384175594-4925-3-git-send-email-jerlbeck@sysmocom.de> This was basically a link to configure/ipa which is not cleanly supported by the current VTY framework. The test program uses the default implementation for go_parent_cb/vty_go_parent() and is_config_node, since config-ipa is a top level config node which is assumed by default. --- src/ipa_proxy.c | 8 -------- tests/ipa_proxy_test.c | 22 ---------------------- 2 files changed, 30 deletions(-) diff --git a/src/ipa_proxy.c b/src/ipa_proxy.c index 30840ef..0c177a2 100644 --- a/src/ipa_proxy.c +++ b/src/ipa_proxy.c @@ -208,13 +208,6 @@ ipa_sock_src_accept_cb(struct ipa_server_link *link, int fd) /* * VTY commands for IPA */ -DEFUN(ipa_proxy, ipa_cmd, "ipa", "Configure the ipaccess proxy") -{ - vty->index = NULL; - vty->node = L_IPA_NODE; - return CMD_SUCCESS; -} - static int __ipa_instance_add(struct vty *vty, int argc, const char *argv[]) { struct ipa_proxy_instance *ipi; @@ -649,7 +642,6 @@ void ipa_proxy_vty_init(void) tall_ipa_proxy_ctx = talloc_named_const(libosmo_abis_ctx, 1, "ipa_proxy"); - install_element(ENABLE_NODE, &ipa_cmd); install_element(ENABLE_NODE, &ipa_instance_add_cmd); install_element(ENABLE_NODE, &ipa_instance_del_cmd); install_element(ENABLE_NODE, &ipa_instance_show_cmd); diff --git a/tests/ipa_proxy_test.c b/tests/ipa_proxy_test.c index 2ed30ff..8f4533c 100644 --- a/tests/ipa_proxy_test.c +++ b/tests/ipa_proxy_test.c @@ -28,31 +28,9 @@ const struct log_info ipa_proxy_test_log_info = { .num_cat = ARRAY_SIZE(ipa_proxy_test_cat), }; -static int bsc_vty_is_config_node(struct vty *vty, int node) -{ - switch(node) { - case L_IPA_NODE: - return 1; - break; - } - return 0; -} - -static enum node_type bsc_vty_go_parent(struct vty *vty) -{ - switch (vty->node) { - case L_IPA_NODE: - vty->node = VIEW_NODE; - break; - } - return vty->node; -} - static struct vty_app_info vty_info = { .name = "ipa-proxy-test", .version = "1.0", - .go_parent_cb = bsc_vty_go_parent, - .is_config_node = bsc_vty_is_config_node, }; #define IPA_PROXY_TEST_TELNET_PORT 4260 -- 1.7.9.5 From lnve at s21sec.com Mon Nov 11 22:58:56 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Mon, 11 Nov 2013 23:58:56 +0100 Subject: Signalling in OpenBSC - LCR - Asterisk Message-ID: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> Has anyone experienced problems with signalling using LCR/Asterisk? In my infrastructure everything goes ok calling from MT to external phones using Asterisk, but when the external one (SIP or extension ended with Hangup() ) the call remains activated at the MT (OpenBSC side). I will make a SIP capture tomorrow, and send it. -- -- Leonardo Nve Project Manager ACSS Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lnve at s21sec.com Tue Nov 12 10:25:34 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Tue, 12 Nov 2013 11:25:34 +0100 Subject: Signalling in OpenBSC - LCR - Asterisk In-Reply-To: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> References: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> Message-ID: <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> Here I send RTP & SIP capture, everything is ok there, and a LCR log. The strange thing at the log i saw is a problem setting Ext port in a Release state. I also send interface.conf. LCR log: 000000 TRACE 12.11.13 01:40:54.228 CH(1): MNCC_SETUP_RSP LCR<->BSC connected type=0 plan=1 present=0 screen=3 number= 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_IN_ALERTING --> PORT_STATE_CONNECT_WAITING 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting tone '' dir '' 000000 TRACE 12.11.13 01:40:54.359 CH(1): MNCC_SETUP_COMPL_IND LCR<->BSC 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_CONNECT_WAITING --> PORT_STATE_CONNECT 000000 DEBUG (in port.cpp/new_state() line 267): PORT(Ext-0-out) new state PORT_STATE_CONNECT --> PORT_STATE_RELEASE 000000 DEBUG (in port.cpp/new_state() line 267): PORT(Ext-0-out) new state PORT_STATE_RELEASE --> PORT_STATE_RELEASE 000000 DEBUG (in remote.cpp/~Premote() line 46): Destroyed Remote process(Ext-0-out). 000000 DEBUG (in port.cpp/~Port() line 215): removing port (2) of type 0x4002, name 'Ext-0-out' interface 'Ext' 000000 DEBUG (in port.cpp/~Port() line 218): Removing us from bridge 1 000000 TRACE 12.11.13 01:40:59.550 EP(2): RELEASE from CH(2) cause value=16 location=1-Local-PBX 000000 TRACE 12.11.13 01:40:59.551 EP(1): TONE to CH(1) directory default name cause_10 000000 TRACE 12.11.13 01:40:59.551 EP(1): DISCONNECT to CH(1) cause value=16 location=1-Local-PBX 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting tone 'cause_10' dir '' 000000 DEBUG (in port.cpp/set_tone() line 367): PORT(GSM-0-in) Given Cause 0x10 has no tone, using release tone 000000 TRACE 12.11.13 01:40:59.551 CH(1): MNCC_DISC_REQ LCR<->BSC progress coding=3 location=1 descr=8 cause coding=3 location=1 value=16 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_CONNECT --> PORT_STATE_OUT_DISCONNECT 000000 DEBUG (in port.cpp/read_audio() line 497): PORT(GSM-0-in) no tone: /opt/lcr/share/lcr/tones_american/release 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop Interface.conf # interface.conf ################ [GSM] gsm-bs #hr tones yes earlyb no # Use chan_lcr (Asterisk PBX interface) as external interface. [Ext] remote asterisk context from-lcr extern earlyb yes tones no El 11/11/2013, a las 23:58, Leonardo Nve escribi?: > Has anyone experienced problems with signalling using LCR/Asterisk? > > In my infrastructure everything goes ok calling from MT to external phones using Asterisk, but when the external one (SIP or extension ended with Hangup() ) the call remains activated at the MT (OpenBSC side). > I will make a SIP capture tomorrow, and send it. > > -- > -- > Leonardo Nve > Project Manager ACSS > Grupo S21sec Gesti?n, S.A. > Telefono 628275870 > -- > > La informaci?n contenida en este mail, as? como los archivos adjuntos,es > CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las > medidas necesarias para asegurar el tratamiento confidencial de los datos > de car?cter personal. En el caso de que el destinatario del correo > no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya > de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la > situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la > empresa remitente realizar acciones legales de diferente envergadura. > > > > > -- -- Leonardo Nve Project Manager ACSS Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: sipRTP.cap Type: application/octet-stream Size: 36534 bytes Desc: not available URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From lnve at s21sec.com Tue Nov 12 10:50:37 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Tue, 12 Nov 2013 11:50:37 +0100 Subject: Signalling in OpenBSC - LCR - Asterisk In-Reply-To: <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> References: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> Message-ID: Finally I send the solution myself: At interface.conf GSM section: tones no Thanks Leo! No problem Leo! Enjoy! El 12/11/2013, a las 11:25, Leonardo Nve escribi?: > Here I send RTP & SIP capture, everything is ok there, and a LCR log. The strange thing at the log i saw is a problem setting Ext port in a Release state. I also send interface.conf. > > LCR log: > 000000 TRACE 12.11.13 01:40:54.228 CH(1): MNCC_SETUP_RSP LCR<->BSC connected type=0 plan=1 present=0 screen=3 number= > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_IN_ALERTING --> PORT_STATE_CONNECT_WAITING > 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting tone '' dir '' > 000000 TRACE 12.11.13 01:40:54.359 CH(1): MNCC_SETUP_COMPL_IND LCR<->BSC > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_CONNECT_WAITING --> PORT_STATE_CONNECT > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(Ext-0-out) new state PORT_STATE_CONNECT --> PORT_STATE_RELEASE > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(Ext-0-out) new state PORT_STATE_RELEASE --> PORT_STATE_RELEASE > 000000 DEBUG (in remote.cpp/~Premote() line 46): Destroyed Remote process(Ext-0-out). > 000000 DEBUG (in port.cpp/~Port() line 215): removing port (2) of type 0x4002, name 'Ext-0-out' interface 'Ext' > 000000 DEBUG (in port.cpp/~Port() line 218): Removing us from bridge 1 > 000000 TRACE 12.11.13 01:40:59.550 EP(2): RELEASE from CH(2) cause value=16 location=1-Local-PBX > 000000 TRACE 12.11.13 01:40:59.551 EP(1): TONE to CH(1) directory default name cause_10 > 000000 TRACE 12.11.13 01:40:59.551 EP(1): DISCONNECT to CH(1) cause value=16 location=1-Local-PBX > 000000 DEBUG (in port.cpp/message_epoint() line 617): PORT(GSM-0-in) setting tone 'cause_10' dir '' > 000000 DEBUG (in port.cpp/set_tone() line 367): PORT(GSM-0-in) Given Cause 0x10 has no tone, using release tone > 000000 TRACE 12.11.13 01:40:59.551 CH(1): MNCC_DISC_REQ LCR<->BSC progress coding=3 location=1 descr=8 cause coding=3 location=1 value=16 > 000000 DEBUG (in port.cpp/new_state() line 267): PORT(GSM-0-in) new state PORT_STATE_CONNECT --> PORT_STATE_OUT_DISCONNECT > 000000 DEBUG (in port.cpp/read_audio() line 497): PORT(GSM-0-in) no tone: /opt/lcr/share/lcr/tones_american/release > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > 000000 DEBUG (in port.cpp/read_audio() line 600): PORT(GSM-0-in) opening tone: /opt/lcr/share/lcr/tones_american/release_loop > > Interface.conf > # interface.conf > ################ > > > [GSM] > gsm-bs > #hr > tones yes > earlyb no > > # Use chan_lcr (Asterisk PBX interface) as external interface. > [Ext] > remote asterisk > context from-lcr > extern > earlyb yes > tones no > > > > > El 11/11/2013, a las 23:58, Leonardo Nve escribi?: > >> Has anyone experienced problems with signalling using LCR/Asterisk? >> >> In my infrastructure everything goes ok calling from MT to external phones using Asterisk, but when the external one (SIP or extension ended with Hangup() ) the call remains activated at the MT (OpenBSC side). >> I will make a SIP capture tomorrow, and send it. >> >> -- >> -- >> Leonardo Nve >> Project Manager ACSS >> Grupo S21sec Gesti?n, S.A. >> Telefono 628275870 >> -- >> >> La informaci?n contenida en este mail, as? como los archivos adjuntos,es >> CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las >> medidas necesarias para asegurar el tratamiento confidencial de los datos >> de car?cter personal. En el caso de que el destinatario del correo >> no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya >> de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la >> situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la >> empresa remitente realizar acciones legales de diferente envergadura. >> >> >> >> >> > > -- > -- > Leonardo Nve > Project Manager ACSS > Grupo S21sec Gesti?n, S.A. > Telefono 628275870 > -- > > La informaci?n contenida en este mail, as? como los archivos adjuntos,es > CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las > medidas necesarias para asegurar el tratamiento confidencial de los datos > de car?cter personal. En el caso de que el destinatario del correo > no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya > de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la > situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la > empresa remitente realizar acciones legales de diferente envergadura. > > > > > -- -- Leonardo Nve Project Manager ACSS Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter at stuge.se Tue Nov 12 15:56:35 2013 From: peter at stuge.se (Peter Stuge) Date: Tue, 12 Nov 2013 16:56:35 +0100 Subject: Signalling in OpenBSC - LCR - Asterisk In-Reply-To: <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> References: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> Message-ID: <20131112155636.16390.qmail@stuge.se> Leonardo Nve wrote: > # Use chan_lcr (Asterisk PBX interface) as external interface. > [Ext] > remote asterisk Why not use sip instead of chan_lcr? //Peter From lnve at s21sec.com Tue Nov 12 17:20:05 2013 From: lnve at s21sec.com (Leonardo Nve) Date: Tue, 12 Nov 2013 18:20:05 +0100 Subject: Signalling in OpenBSC - LCR - Asterisk In-Reply-To: <20131112155636.16390.qmail@stuge.se> References: <08E50F36-84E1-4788-9D6B-08171DCA5F74@s21sec.com> <45B24E16-51D2-4DEA-B415-6AF0E52142E6@s21sec.com> <20131112155636.16390.qmail@stuge.se> Message-ID: <57E53F97-CFC5-40A0-9B69-CE2D5DA06EC7@s21sec.com> Because the communication is better with chan_lcr than using SIP, I also see less CPU usage. Are there any special reason to use SIP? (apart integration with other providers) -- Leonardo Nve Project Manager departamento Auditoria Grupo S21sec Gesti?n, S.A. Telefono 628275870 -- La informaci?n contenida en este mail, as? como los archivos adjuntos,es CONFIDENCIAL. Grupo S21sec Gesti?n, S.A. garantiza la adopci?n de las medidas necesarias para asegurar el tratamiento confidencial de los datos de car?cter personal. En el caso de que el destinatario del correo no sea usted, le rogamos env?e una notificaci?n al remitente y lo destruya de forma inmediata. La lectura y/o manipulaci?n de esta informaci?n en la situaci?n se?alada anteriormente ser? considerada ilegal, permitiendo a la empresa remitente realizar acciones legales de diferente envergadura. El 12/11/2013, a las 16:56, Peter Stuge escribi?: > Leonardo Nve wrote: >> # Use chan_lcr (Asterisk PBX interface) as external interface. >> [Ext] >> remote asterisk > > Why not use sip instead of chan_lcr? > > > //Peter > From alexander.chemeris at gmail.com Tue Nov 12 10:58:37 2013 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 12 Nov 2013 12:58:37 +0200 Subject: Meet us at AfricaCom Message-ID: Hi all, Fairwaves team is in Cape Town at AfricaCom from today to Thursday. Drop me an SMS to +7(915)330-7626 and we would be happy to arrange a meeting. Fairwaves is a complete solution provider and "just a BTS" vendor. We provide turn-key GSM networks with VoIP backhaul, as well as BTS/BSC for existing GSM networks extension. Our partnerships with the leading VoIP providers allows us to provide your subscribers with the lowest calling rates. Voice and SMS programming platform we offer, allows you to implement complex value added services simpler, than with Twilio. PS Read about the exciting project we're doing in Mexico with the Rhizomatica.org team: https://fairwaves.ru/wp/telecom-revolution-starts-in-yaviche-mexico/ -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From laforge at gnumonks.org Tue Nov 12 17:31:52 2013 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 12 Nov 2013 18:31:52 +0100 Subject: Meet us at AfricaCom In-Reply-To: References: Message-ID: <20131112173152.GE23234@nataraja.gnumonks.org> Dear Alexander, please immediately stop using this (or any other osmocom.org mailing list) for commercial advertisement and marketing of any sort. If you check the history of this list, you will notice that Holger and I at sysmoco always have drawn a _very_ clear line and did never abuse the community lists for any kind of spam. Despite us funding the OsmoDevCon, paying for osmocom.org hosting, etc. The same holds true for the *.osmocom.org web sites. We expect the same discretion from other subscribers. To be honest, I would have expected more sensitivity from you regarding the use of FOSS community communication channels for unsolicited commercial email. I will immediately remove your advertisement from the list archives. The only posts of commercial nature that I can recall are the occasional single-unit second hand sale of nanoBTSs and related equipment by individual subscribers. I consider that fair use, as it is of course in the interest of OpenBSC to enable community members to get access to inexpensive equipment for R&D, testing, etc. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From alexander.chemeris at gmail.com Tue Nov 12 22:15:00 2013 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 13 Nov 2013 00:15:00 +0200 Subject: Meet us at AfricaCom In-Reply-To: <20131112173152.GE23234@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> Message-ID: HI Harald, I appreciate your care about the community and I won't post anything related to our commercial activities to this mailing list from now on. But I should say, that I disagree with you in your assessment of my e-mail as spam. I always care about community and gauge all my posts from a user perspective, and I wouldn't classify this as a spam. My reasoning is as following: 1. If I'm a user of Osmocom, I'd be interested in meeting a vendor in person, given a good occasion. 2. If I'm a user of Osmocom, I'd be interested in announcements of new products, compatible with Osmocom (this is a general comment, unrelated to this exact e-mail). May be we should create a separate (low-traffic) mailing list for commercial announcements, related to Osmocom? That might be a useful way to promote a healthy ecosystem around it. On Tue, Nov 12, 2013 at 7:31 PM, Harald Welte wrote: > Dear Alexander, > > please immediately stop using this (or any other osmocom.org mailing > list) for commercial advertisement and marketing of any sort. > > If you check the history of this list, you will notice that Holger and I > at sysmoco always have drawn a _very_ clear line and did never abuse the > community lists for any kind of spam. Despite us funding the > OsmoDevCon, paying for osmocom.org hosting, etc. The same holds true > for the *.osmocom.org web sites. We expect the same discretion from > other subscribers. > > To be honest, I would have expected more sensitivity from you regarding > the use of FOSS community communication channels for unsolicited > commercial email. > > I will immediately remove your advertisement from the list archives. > > The only posts of commercial nature that I can recall are the occasional > single-unit second hand sale of nanoBTSs and related equipment by > individual subscribers. I consider that fair use, as it is of course in > the interest of OpenBSC to enable community members to get access to > inexpensive equipment for R&D, testing, etc. > > Regards, > Harald > -- > - Harald Welte http://laforge.gnumonks.org/ > ============================================================================ > "Privacy in residential applications is a desirable marketing option." > (ETSI EN 300 175-7 Ch. A6) -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From laforge at gnumonks.org Wed Nov 13 11:51:34 2013 From: laforge at gnumonks.org (Harald Welte) Date: Wed, 13 Nov 2013 12:51:34 +0100 Subject: no commercial announcements to this list In-Reply-To: References: <20131112173152.GE23234@nataraja.gnumonks.org> Message-ID: <20131113115134.GP9310@nataraja.gnumonks.org> Hi Alexander, On Wed, Nov 13, 2013 at 12:15:00AM +0200, Alexander Chemeris wrote: > I appreciate your care about the community and I won't post anything > related to our commercial activities to this mailing list from now on. thanks for your attention. Regarding SPAM: Well, then let's call it 'UCE' (unsolicited commercial email). The typical list member is somebody interested in using or developing OpenBSC. By no means has he ever explicitly given us permission to send him advertisements of any sort. So it is unsolicited. and it is commercial. and it is email. This list is for technical discussion around the development [and use] of OpenBSC. But if we open it for commercial announcements, you will have a dozen of companies sending weekly updates on their ever-so-shiny new products, and the deveopers will leave and go elsewhere where they are not bothered by it. > May be we should create a separate (low-traffic) mailing list for > commercial announcements, related to Osmocom? That might be a useful > way to promote a healthy ecosystem around it. I'm happy to create such a list, but I have a hard time that anyone would be interested in subscribing it. So if anyone reading this message is intersted in such a new list for commercial/product announcements, please respond to this message. I admit I'm extremely allergic to all kinds of spam/advertisements/marketing, and my view might be a bit more extreme than others. Anything that any vendor can ever hope to achieve by sending SPAM/UCE/UBE to me is that I get upset and will intentionally penalize him by not buying from him because he has sent me unsolicited mail. 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 ralph at schmid.xxx Wed Nov 13 12:12:20 2013 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Wed, 13 Nov 2013 13:12:20 +0100 Subject: no commercial announcements to this list In-Reply-To: <20131113115134.GP9310@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> Message-ID: <000601cee069$9af63e20$d0e2ba60$@schmid.xxx> Hi, > I'm happy to create such a list, but I have a hard time that anyone would be > interested in subscribing it. So if anyone reading this message is intersted in > such a new list for commercial/product announcements, please respond to > this message. *respond* :-) I am glad about every bit of information regarding SDR/BTS stuff, may it be commercial or not. So for sure I will subscribe to this list, as long as it stays osmocom-related. > I admit I'm extremely allergic to all kinds of spam/advertisements/marketing, > and my view might be a bit more extreme than others. Anything that any > vendor can ever hope to achieve by sending SPAM/UCE/UBE to me is that I > get upset and will intentionally penalize him by not buying from him because > he has sent me unsolicited mail. My behavior is similar, just my tolerance level to sort something into the SPAM/UCE class may be a bit higher. > Regards, > Harald Ralph. From holger at freyther.de Wed Nov 13 12:22:52 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 13 Nov 2013 13:22:52 +0100 Subject: no commercial announcements to this list In-Reply-To: <20131113115134.GP9310@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> Message-ID: <20131113122252.GB21722@xiaoyu.lan> On Wed, Nov 13, 2013 at 12:51:34PM +0100, Harald Welte wrote: > I admit I'm extremely allergic to all kinds of > spam/advertisements/marketing, and my view might be a bit more extreme > than others. Anything that any vendor can ever hope to achieve by > sending SPAM/UCE/UBE to me is that I get upset and will intentionally > penalize him by not buying from him because he has sent me unsolicited > mail. I am allergic to this as well. Just to test it I went to the asterisk website and looked how many times I need to click to end up on the digium website. I don't want osmocom to become like that and I think your reaction was the right one. The osmocom project is not a sales/marketing channel... holger From peter at stuge.se Wed Nov 13 17:57:01 2013 From: peter at stuge.se (Peter Stuge) Date: Wed, 13 Nov 2013 18:57:01 +0100 Subject: no commercial announcements to this list In-Reply-To: <20131113122252.GB21722@xiaoyu.lan> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> Message-ID: <20131113175701.32090.qmail@stuge.se> Holger Hans Peter Freyther wrote: > > I admit I'm extremely allergic to all kinds of > > spam/advertisements/marketing, and my view might be a bit more extreme > > than others. Anything that any vendor can ever hope to achieve by > > sending SPAM/UCE/UBE to me is that I get upset and will intentionally > > penalize him by not buying from him because he has sent me unsolicited > > mail. > > I am allergic to this as well. Just to test it I went to the asterisk > website and looked how many times I need to click to end up on the > digium website. > > I don't want osmocom to become like that and I think your reaction was > the right one. I agree with you and Harald here. > The osmocom project is not a sales/marketing channel... I don't agree with this however - I think the osmocom project, like all other open source projects, is a wonderful marketing channel. But the marketing is very different - the marketing is simply a byproduct of high quality development effort. Whoever does good work becomes better known, which in turn makes it more likely for them to be contacted about commercial activity. But, like Harald and Holger I too think that it's important to draw a clear line between simple advertisement "we can do things" and actual contributions "here's a patch which we've done". Alexander, the way to generate support isn't to tell people what one can do, but to let them discover it on their own. But there is also a bootstrapping problem, and I think it *is* in the interest of the open source project to help those who seek commercial products and services which contribute to the project to find the right suppliers. On the other hand nobody has a vested interest in keeping such a registry up to date, in particular getting rid of old information is difficult. The best solution may be based on the code: Someone who wants to sell products can work on visualizing how well their product works, in a way that is also generally relevant for the open source project. An automated test system is a good example, with clear red/green indication of how well a given product works over time. Of course, building test jigs for actual hardware is quite a bit more difficult (read: expensive) than for software, so it remains tempting to send simple advertisements. But please realise that advertisements do more harm than good in the long run, in the context of open source projects. I'd like to point out that I think it was a good idea for Alexander to send an email saying that he was at the conference and inviting to meet up with anyone who wanted to chat - only the blatant advertising in the email was stepping over the line IMO. //Peter From laforge at gnumonks.org Thu Nov 14 12:36:42 2013 From: laforge at gnumonks.org (Harald Welte) Date: Thu, 14 Nov 2013 13:36:42 +0100 Subject: no commercial announcements to this list In-Reply-To: <20131113175701.32090.qmail@stuge.se> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> <20131113175701.32090.qmail@stuge.se> Message-ID: <20131114123642.GT11360@nataraja.gnumonks.org> Hi Peter, thanks for your feedback. On Wed, Nov 13, 2013 at 06:57:01PM +0100, Peter Stuge wrote: > I agree with you and Harald here. To avoid any doubt, I have updated the mailing list rules http://openbsc.osmocom.org/trac/wiki/MailingListRules to include a chapter about spam/uce/ube. So at least from now on, nobody can claim that it was not clear that such postings are not welcome. > But there is also a bootstrapping problem, and I think it *is* in the > interest of the open source project to help those who seek commercial > products and services which contribute to the project to find the > right suppliers. If some OpenBSC users inquired on the list here about commercial support, I wouldn't consider a simple response like 'we are providing commercial support' wrong. I just don't think they deserve to be sent advertisements before they even raised the question. > I'd like to point out that I think it was a good idea for Alexander > to send an email saying that he was at the conference and inviting > to meet up with anyone who wanted to chat - only the blatant > advertising in the email was stepping over the line IMO. I agree here, too. If it was just an "I'm at this or that conference, OpenBSC users/developers interested in meeting up, please contact me" then it would be outside of a marketing/advertising context, and merely folks interested in OpenBSC meeting up. Regarding a separate list for commercial offerings surrounding OpenBSC or other osmocom projects: I'm open for that, and at least two people have indicated interest in subscribing to it. Now we only need to find a name for the list to go ahead. 'osmocom-advertisements' is not correct, as the list is not about advertising Osmocom itself, but products using it / compatible with it. 'osmocom-products' is also not exactly correct. Any better ideas? 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 andrew at carrierdetect.com Thu Nov 14 12:47:22 2013 From: andrew at carrierdetect.com (Andrew Back) Date: Thu, 14 Nov 2013 12:47:22 +0000 Subject: no commercial announcements to this list In-Reply-To: <20131114123642.GT11360@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> <20131113175701.32090.qmail@stuge.se> <20131114123642.GT11360@nataraja.gnumonks.org> Message-ID: Hi Harald, On 14 November 2013 12:36, Harald Welte wrote: > Hi Peter, > > thanks for your feedback. > > On Wed, Nov 13, 2013 at 06:57:01PM +0100, Peter Stuge wrote: >> I agree with you and Harald here. > > To avoid any doubt, I have updated the mailing list rules > http://openbsc.osmocom.org/trac/wiki/MailingListRules > to include a chapter about spam/uce/ube. So at least from now on, > nobody can claim that it was not clear that such postings are not > welcome. > >> But there is also a bootstrapping problem, and I think it *is* in the >> interest of the open source project to help those who seek commercial >> products and services which contribute to the project to find the >> right suppliers. > > If some OpenBSC users inquired on the list here about commercial > support, I wouldn't consider a simple response like 'we are providing > commercial support' wrong. I just don't think they deserve to be sent > advertisements before they even raised the question. > >> I'd like to point out that I think it was a good idea for Alexander >> to send an email saying that he was at the conference and inviting >> to meet up with anyone who wanted to chat - only the blatant >> advertising in the email was stepping over the line IMO. > > I agree here, too. If it was just an "I'm at this or that conference, > OpenBSC users/developers interested in meeting up, please contact me" > then it would be outside of a marketing/advertising context, and merely > folks interested in OpenBSC meeting up. > > Regarding a separate list for commercial offerings surrounding OpenBSC > or other osmocom projects: I'm open for that, and at least two people > have indicated interest in subscribing to it. Now we only need to find > a name for the list to go ahead. 'osmocom-advertisements' is not > correct, as the list is not about advertising Osmocom itself, but > products using it / compatible with it. 'osmocom-products' is also not > exactly correct. Any better ideas? How about 'product-announce' or 'commercial-announce' (to include services)? Best, Andrew -- Andrew Back http://carrierdetect.com From alexander.chemeris at gmail.com Sun Nov 17 19:23:52 2013 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 17 Nov 2013 23:23:52 +0400 Subject: no commercial announcements to this list In-Reply-To: <20131114123642.GT11360@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> <20131113175701.32090.qmail@stuge.se> <20131114123642.GT11360@nataraja.gnumonks.org> Message-ID: On Thu, Nov 14, 2013 at 4:36 PM, Harald Welte wrote: >> I'd like to point out that I think it was a good idea for Alexander >> to send an email saying that he was at the conference and inviting >> to meet up with anyone who wanted to chat - only the blatant >> advertising in the email was stepping over the line IMO. > > I agree here, too. If it was just an "I'm at this or that conference, > OpenBSC users/developers interested in meeting up, please contact me" > then it would be outside of a marketing/advertising context, and merely > folks interested in OpenBSC meeting up. Btw, I plan to organize a long planned OpenBSC meetup in Boston and may be in Mexico. Will send an e-mail about that in few minutes. > Regarding a separate list for commercial offerings surrounding OpenBSC > or other osmocom projects: I'm open for that, and at least two people > have indicated interest in subscribing to it. Now we only need to find > a name for the list to go ahead. 'osmocom-advertisements' is not > correct, as the list is not about advertising Osmocom itself, but > products using it / compatible with it. 'osmocom-products' is also not > exactly correct. Any better ideas? Simply 'osmocom-commercial'? -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From laforge at gnumonks.org Fri Nov 22 15:58:04 2013 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 22 Nov 2013 16:58:04 +0100 Subject: no commercial announcements to this list In-Reply-To: References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> <20131113175701.32090.qmail@stuge.se> <20131114123642.GT11360@nataraja.gnumonks.org> Message-ID: <20131122155804.GK18191@nataraja.gnumonks.org> Hi Alexander, On Sun, Nov 17, 2013 at 11:23:52PM +0400, Alexander Chemeris wrote: > > Regarding a separate list for commercial offerings surrounding OpenBSC > > or other osmocom projects: I'm open for that, and at least two people > > have indicated interest in subscribing to it. Now we only need to find > > a name for the list to go ahead. 'osmocom-advertisements' is not > > correct, as the list is not about advertising Osmocom itself, but > > products using it / compatible with it. 'osmocom-products' is also not > > exactly correct. Any better ideas? > > Simply 'osmocom-commercial'? fine. List has been created. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From alexander.chemeris at gmail.com Sun Nov 17 19:17:02 2013 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 17 Nov 2013 23:17:02 +0400 Subject: no commercial announcements to this list In-Reply-To: <20131113175701.32090.qmail@stuge.se> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> <20131113122252.GB21722@xiaoyu.lan> <20131113175701.32090.qmail@stuge.se> Message-ID: Hi all, On Wed, Nov 13, 2013 at 9:57 PM, Peter Stuge wrote: > I'd like to point out that I think it was a good idea for Alexander > to send an email saying that he was at the conference and inviting > to meet up with anyone who wanted to chat - only the blatant > advertising in the email was stepping over the line IMO. I think Peter put it in the best way. I wrote that e-mail in rush and failed to properly switch context in my mind from sales to hacker. Will add more safety checks around that procedure for future. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From 246tnt at gmail.com Thu Nov 14 08:45:53 2013 From: 246tnt at gmail.com (Sylvain Munaut) Date: Thu, 14 Nov 2013 09:45:53 +0100 Subject: no commercial announcements to this list In-Reply-To: <20131113115134.GP9310@nataraja.gnumonks.org> References: <20131112173152.GE23234@nataraja.gnumonks.org> <20131113115134.GP9310@nataraja.gnumonks.org> Message-ID: Hi, > Regarding SPAM: Well, then let's call it 'UCE' (unsolicited commercial > email). The typical list member is somebody interested in using or > developing OpenBSC. By no means has he ever explicitly given us > permission to send him advertisements of any sort. So it is > unsolicited. and it is commercial. and it is email. +1 > I'm happy to create such a list, but I have a hard time that anyone > would be interested in subscribing it. So if anyone reading this > message is intersted in such a new list for commercial/product > announcements, please respond to this message. I can say for sure I wouldn't be interested and wouldn't subscribe. If a company uses Osmocom stuff in its products, either I already know it from its contribution to the codebase, or I'm not interested in what it has to sell anyway. Cheers, Sylvain From rodent at rodent.za.net Thu Nov 14 00:39:42 2013 From: rodent at rodent.za.net (Roelf Diedericks) Date: Thu, 14 Nov 2013 02:39:42 +0200 Subject: Meet us at AfricaCom Message-ID: I met with Alexander today at AfricaCom, and as an interested user of OsmoCOM and the proud owner of a SysmoBTS I can say that the email was certainly of interest to me. It is a very small community, and whilst commercial spamming shouldn't be allowed, I do feel that for the very small special interest group we all participate in, some relaxed attitude may be warranted. The list is currently unobtrusive and if it ever gets as busy as LKML, I'm sure we can do some benevolent dicatatoring. If it were Huawei spamming the list about the conference, then I'd agree, but the Fairwaves guys have generously opened up their hardware designs as well. I don't think it gets more open than that... Regards, Roelf. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmi3sol at gmail.com Tue Nov 19 11:26:16 2013 From: dmi3sol at gmail.com (Dmitri Soloviev) Date: Tue, 19 Nov 2013 15:26:16 +0400 Subject: Huawei "CAMEL" in between USAU and SCP Message-ID: Hi list I'm hacking a protocol that runs inside Huawei SCP, in between USAU (signaling gateway within IN) and SCP node itself. There is a small file at my disposal (few megs), to study. Unfortunately there is no way to run a trace at the other side of USAU in parallel, so need to guess about fields. Here is the typical IDP found with my guestimations 000000a7 - packet length 0000feab - packet ID 00a1 - length of remained portion 1000 - (***) protocol type, 0x1000 is similar to CAMEL, other protocols are {0100,0200,0300,0400,0500,0600,1000,1200,1300,1400,1500,1700} 01d6f100 - transaction ID 01d6f100 01ff - msg type and direction, 01FF - IDP, where FF means that it goes from gsmSCP to gsmSCP, response is 0100 0000010000000000 - something unknown, some messages may have non-zero values here 8c - length 30 81 - tag+len, something like IDP args 89 8001 01 82 08 84 90 xxxxxxxxxxxx - A pty, MSISDN 83 08 84 13 xxxxxxxxxxxx - B pty, MSISDN 85 01 0a 88 04 00000000 8a 04 84 13 xxxx - E.164 country code bb 05 80038090a3 9c 01 0c 9f32 08 xxxxxxxxxxxxxxxx - IMSI (A) bf33 02 8000 bf34 - a tag that assumes no length/value 22 02 0159 80 08 1000000000000000 81 08 91 xxxxxxxxxxxxxxx - GT of MSC(ssf) a3 09 8007 xxxxxxxxxxxxxx location number ? bf35 03 830111 9f36 05 207a77c430 9f37 08 91 xxxxxxxxxxxxxx - GT of MSC(ssf) 9f39 08 xxxxxxxxxxxxxxxx - some number in unknown format (neither E.164 nor E.212) a-pty MSISDN may be alternatively coded with 9F38 tag The most tricky thing is to decode another protocol types (marked with *** above) that are not so obvious My final goal is to decode both CAP portion and amount of credit available Is there anybody who faced similar task or who can provide additional traces.. or can even make some traces? An ideal case is to perform SS7 and USAU trace in parallel. Or even has some papers on this topic Regards, Dmitri Soloviev -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Tue Nov 19 18:46:47 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 19 Nov 2013 19:46:47 +0100 Subject: Huawei "CAMEL" in between USAU and SCP In-Reply-To: References: Message-ID: <20131119184647.GL31731@xiaoyu.lan> On Tue, Nov 19, 2013 at 03:26:16PM +0400, Dmitri Soloviev wrote: > bf33 02 8000 > bf34 - a tag that assumes no length/value are you sure? Can your bytearray be Hex Decoded? > My final goal is to decode both CAP portion and amount of credit available I assume you don't want to initiate a USSD query toward the gsmSCF to ask for the balance this way? > > Is there anybody who faced similar task or who can provide additional > traces.. or can even make some traces? > An ideal case is to perform SS7 and USAU trace in parallel. > Or even has some papers on this topic sorry. I didn't have access to Huawei equipment yet. From Max.Suraev at fairwaves.ru Tue Nov 19 12:21:09 2013 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Tue, 19 Nov 2013 13:21:09 +0100 Subject: [PATCH] Use generic osmocom auth api Message-ID: <528B57B5.7080400@fairwaves.ru> Hi. Attached is a small patch which replaces direct call to comp128 from libosmocore to auth api call. This will help to remove comp128 from libosmocore public api and to use other auth functions in openbsc in future. -- best regards, Max, http://fairwaves.ru From max.suraev at fairwaves.ru Tue Nov 19 12:16:26 2013 From: max.suraev at fairwaves.ru (Max) Date: Tue, 19 Nov 2013 13:16:26 +0100 Subject: [PATCH] Use generic osmocom auth api instead of direct call to comp128. Message-ID: --- openbsc/src/libmsc/auth.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/openbsc/src/libmsc/auth.c b/openbsc/src/libmsc/auth.c index 10d8edf..33d4a3a 100644 --- a/openbsc/src/libmsc/auth.c +++ b/openbsc/src/libmsc/auth.c @@ -24,8 +24,7 @@ #include #include #include - -#include +#include #include @@ -60,9 +59,17 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) return -1; } - comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc); - - return 0; + static struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1 + }; + memcpy(auth.u.gsm.ki, ainfo->a3a8_ki, sizeof(auth.u.gsm.ki)); + struct osmo_auth_vector _vec; + struct osmo_auth_vector *vec = &_vec; + int r = osmo_auth_gen_vec(vec, &auth, atuple->rand); + memcpy(atuple->sres, vec->sres, 4); + memcpy(atuple->kc, vec->kc, 8); + return r; } /* Return values -- 1.8.3.2 --------------070009030406090002040109-- From peter at stuge.se Tue Nov 19 12:32:47 2013 From: peter at stuge.se (Peter Stuge) Date: Tue, 19 Nov 2013 13:32:47 +0100 Subject: [PATCH] Use generic osmocom auth api In-Reply-To: <528B57B5.7080400@fairwaves.ru> References: <528B57B5.7080400@fairwaves.ru> Message-ID: <20131119123247.6807.qmail@stuge.se> Hi, ? wrote: > Attached is a small patch which replaces direct call to comp128 > from libosmocore to auth api call. Thanks! > +++ b/openbsc/src/libmsc/auth.c .. > @@ -60,9 +59,17 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) > return -1; > } > > - comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc); > - > - return 0; > + static struct osmo_sub_auth_data auth = { > + .type = OSMO_AUTH_TYPE_GSM, > + .algo = OSMO_AUTH_ALG_COMP128v1 > + }; > + memcpy(auth.u.gsm.ki, ainfo->a3a8_ki, sizeof(auth.u.gsm.ki)); > + struct osmo_auth_vector _vec; > + struct osmo_auth_vector *vec = &_vec; > + int r = osmo_auth_gen_vec(vec, &auth, atuple->rand); > + memcpy(atuple->sres, vec->sres, 4); > + memcpy(atuple->kc, vec->kc, 8); > + return r; > } Maybe add a newline or two, and I think the openbsc style is to declare all variables at the start of the function. //Peter From Max.Suraev at fairwaves.ru Tue Nov 19 12:45:14 2013 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Tue, 19 Nov 2013 13:45:14 +0100 Subject: [PATCH] Use generic osmocom auth api In-Reply-To: <20131119123247.6807.qmail@stuge.se> References: <528B57B5.7080400@fairwaves.ru> <20131119123247.6807.qmail@stuge.se> Message-ID: <528B5D5A.2020605@fairwaves.ru> Improved version attached. 19.11.2013 13:32, Peter Stuge ?????: > Hi, > > ? wrote: >> Attached is a small patch which replaces direct call to comp128 >> from libosmocore to auth api call. > > Thanks! > > >> +++ b/openbsc/src/libmsc/auth.c > .. >> @@ -60,9 +59,17 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) >> return -1; >> } >> >> - comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc); >> - >> - return 0; >> + static struct osmo_sub_auth_data auth = { >> + .type = OSMO_AUTH_TYPE_GSM, >> + .algo = OSMO_AUTH_ALG_COMP128v1 >> + }; >> + memcpy(auth.u.gsm.ki, ainfo->a3a8_ki, sizeof(auth.u.gsm.ki)); >> + struct osmo_auth_vector _vec; >> + struct osmo_auth_vector *vec = &_vec; >> + int r = osmo_auth_gen_vec(vec, &auth, atuple->rand); >> + memcpy(atuple->sres, vec->sres, 4); >> + memcpy(atuple->kc, vec->kc, 8); >> + return r; >> } > > Maybe add a newline or two, and I think the openbsc style is to > declare all variables at the start of the function. > > > //Peter > -- best regards, Max, http://fairwaves.ru From max.suraev at fairwaves.ru Tue Nov 19 12:42:44 2013 From: max.suraev at fairwaves.ru (Max) Date: Tue, 19 Nov 2013 13:42:44 +0100 Subject: [PATCH] Use generic libosmocom auth API. Message-ID: --- openbsc/src/libmsc/auth.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libmsc/auth.c b/openbsc/src/libmsc/auth.c index 10d8edf..ed25495 100644 --- a/openbsc/src/libmsc/auth.c +++ b/openbsc/src/libmsc/auth.c @@ -24,8 +24,7 @@ #include #include #include - -#include +#include #include @@ -53,6 +52,13 @@ _use_xor(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) static int _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) { + static struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1 + }; + struct osmo_auth_vector _vec; + struct osmo_auth_vector *vec = &_vec; + if (ainfo->a3a8_ki_len != A38_COMP128_KEY_LEN) { LOGP(DMM, LOGL_ERROR, "Invalid COMP128v1 key (len=%d) %s\n", ainfo->a3a8_ki_len, @@ -60,9 +66,13 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) return -1; } - comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc); + memcpy(auth.u.gsm.ki, ainfo->a3a8_ki, sizeof(auth.u.gsm.ki)); - return 0; + int r = osmo_auth_gen_vec(vec, &auth, atuple->rand); + memcpy(atuple->sres, vec->sres, 4); + memcpy(atuple->kc, vec->kc, 8); + + return r; } /* Return values -- 1.8.3.2 --------------060000020105010100080006-- From laforge at gnumonks.org Fri Nov 22 16:07:29 2013 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 22 Nov 2013 17:07:29 +0100 Subject: [PATCH] Use generic osmocom auth api In-Reply-To: <528B57B5.7080400@fairwaves.ru> References: <528B57B5.7080400@fairwaves.ru> Message-ID: <20131122160729.GM18191@nataraja.gnumonks.org> Hi Max, thanks for your patch. I think it would make more sense to 1) add XOR to libosmocore 2) have a table or function to map from AUTH_ALGO_COMP128v1 to OSMO_AUTH_ALG_COMP128v1 (as well as mappings for any other ciphers at that time, _use_xor() / _use_comp128_v1() become superfluous, and auth_get_tuple_for_subscr() can call osmo_auth_gen_vec() directly. This way, adding more algorithms only has to add mappings for the AUTH_ALGO_* to OSMO_AUTH_ALG_ values (and a way how the vty can change the algorithm for a given subscriber). What do you think? 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 Max.Suraev at fairwaves.ru Fri Nov 22 16:34:25 2013 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Fri, 22 Nov 2013 17:34:25 +0100 Subject: [PATCH] Use generic osmocom auth api In-Reply-To: <20131122160729.GM18191@nataraja.gnumonks.org> References: <528B57B5.7080400@fairwaves.ru> <20131122160729.GM18191@nataraja.gnumonks.org> Message-ID: <528F8791.20405@fairwaves.ru> 22.11.2013 17:07, Harald Welte ?????: > Hi Max, > > thanks for your patch. > > I think it would make more sense to > > 1) add XOR to libosmocore Was it actually used for anything besides internal testing inside OpenBSC? I do not recall seeing xor "hash function" in gsm spec, so I'm not sure it will be generally useful except for giving nightmares to security researchers :) > 2) have a table or function to map from AUTH_ALGO_COMP128v1 to > OSMO_AUTH_ALG_COMP128v1 (as well as mappings for any other ciphers > Can we use OSMO_AUTH_ALG_COMP128v1 directly? As far as I can see it's only used to map some text into algorithm in vty code and than use selected algorithm in auth code. What is include/openbsc/gsm_data.h for? > at that time, _use_xor() / _use_comp128_v1() become superfluous, and > auth_get_tuple_for_subscr() can call osmo_auth_gen_vec() directly. > I was thinking to use osmo_auth_gen_vec() and replace gsm_auth_tuple with osmo_auth_vec but I'm not sure what parts of libmsc considered as "stable" api so I opted for minimum-intrusion patches just to get rid of direct access to libosmocore's comp128v* functions. Of course the more generic code from libosmocore is used - the better. -- best regards, Max, http://fairwaves.ru From 246tnt at gmail.com Sun Nov 24 15:52:29 2013 From: 246tnt at gmail.com (Sylvain Munaut) Date: Sun, 24 Nov 2013 16:52:29 +0100 Subject: [PATCH] Use generic osmocom auth api In-Reply-To: <528F8791.20405@fairwaves.ru> References: <528B57B5.7080400@fairwaves.ru> <20131122160729.GM18191@nataraja.gnumonks.org> <528F8791.20405@fairwaves.ru> Message-ID: Hi, >> 1) add XOR to libosmocore > > Was it actually used for anything besides internal testing inside OpenBSC? > I do not recall seeing xor "hash function" in gsm spec, so I'm not sure it will be > generally useful except for giving nightmares to security researchers :) It's used by some test sims and some test equipement. Cheers, Sylvain From Dominik.Tamaskovic at astrium.eads.net Tue Nov 19 13:41:20 2013 From: Dominik.Tamaskovic at astrium.eads.net (TAMASKOVIC, Dominik) Date: Tue, 19 Nov 2013 13:41:20 +0000 Subject: OsmoBTS without HW In-Reply-To: References: Message-ID: Hi, I am working on my Diploma thesis , which topic is GPRS Emulation software. This project is based on your OsmoBTS project . The idea is to delete/replace the hw-related primitives and features and redirect the whole traffic to the osmocomBB with modifications ? this is the work of my colleague . 1st point: My intention is to implement gprs part only. I have analyzed the BTS codes(especially Master, Jolly/l1sap_parts and Jolly/Trx ), i dont know which one will be most suitable to use, but I think the jolly/trx or jolly/l1sap_parts common part will be probably best choise . It implements more common functions in l1sap interface compared to the Master code . Am I right ? 2nd point: I have analyzed the common code, and it is look like the main logic of the PCU(from the BTS side) is implemented in pcu_sock.c and l1sap.c , where the l1sap implements the message parsing and sending to the l1_if of the BTS , and also initializes gsmtap messages . So what I want to do is to create another socket application to connect with osmocomBB(with additional gprs implementation) , which will send/receive the BTS messages from l1sap through our custom "l1 interface" to the osmocomBB phone("how simple") . The PCU part looks, that would not need any intervention. What do you think ? The hardest part will be to achieve , the application will be able to run witout HW (in the case of TRX branch , the bts will be able to connect to "transmiter" ). Since i am now standing on the crossroad, i need advice to make the right discision . Any suggestions and comments are highly appreciated. Best Regards, Dominik Tamaskovic -------------- next part -------------- An HTML attachment was scrubbed... URL: From laforge at gnumonks.org Fri Nov 22 16:03:09 2013 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 22 Nov 2013 17:03:09 +0100 Subject: OsmoBTS without HW In-Reply-To: References: Message-ID: <20131122160309.GL18191@nataraja.gnumonks.org> Hi Dominik, On Tue, Nov 19, 2013 at 01:41:20PM +0000, TAMASKOVIC, Dominik wrote: > I am working on my Diploma thesis , which topic is GPRS Emulation > software. This project is based on your OsmoBTS project . The idea is > to delete/replace the hw-related primitives and features and redirect > the whole traffic to the osmocomBB with modifications ? this is the > work of my colleague . Where can we track the progress of this work? Are you using a private git repository somewhere? Please let us know where your code is. You know where our is ;) The idea of a virtual air interface between OsmoBTS and OsmocomBB has been suggested multiple times. The use of GSMTAP for the 'virtual air interface' has so far been the best conclusion. However, we have not yet received any contributions in that area. > 1st point: My intention is to implement gprs part only. I have > analyzed the BTS codes(especially Master, Jolly/l1sap_parts and > Jolly/Trx ), i dont know which one will be most suitable to use, but > I think the jolly/trx or jolly/l1sap_parts common part will be > probably best choise . It implements more common functions in l1sap > interface compared to the Master code . Am I right ? Correct. > 2nd point: I have analyzed the common code, and it is look like the > main logic of the PCU(from the BTS side) is implemented in pcu_sock.c > and l1sap.c , where the l1sap implements the message parsing and > sending to the l1_if of the BTS , and also initializes gsmtap messages > . So what I want to do is to create another socket application to > connect with osmocomBB(with additional gprs implementation) , which > will send/receive the BTS messages from l1sap through our custom "l1 > interface" to the osmocomBB phone("how simple") . The PCU part looks, > that would not need any intervention. What do you think ? I would prefer if you used GSMTAP messages as the 'virtual air interface'. They are a well-known format for encapsulating GSM Um interface messages at the L1/L2 boundary. You can even have multiple TRXs, as the ARFCN is indicated in the GSMTAP header. And if all BTSs and MSs are using UDP multicast, you can even have multiple BTSs which are seen by multiple phones, etc. Also, at that point, you can analyze the full traffic in wireshark. 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 Thu Nov 21 18:05:42 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 21 Nov 2013 19:05:42 +0100 Subject: [PATCH 1/4] rtp: Fixed size check in padded RTP packets Message-ID: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> This patch fixes a corner case (padding 1, payload size incl padding 0) which is not being detected correctly. Sponsored-by: On-Waves ehf --- openbsc/src/libtrau/rtp_proxy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 0074b4a..4278fc6 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -151,7 +151,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) } } if (rtph->padding) { - if (payload_len < 0) { + if (payload_len < 1) { DEBUGPC(DLMUX, "received RTP frame too short for " "padding length\n"); return -EINVAL; -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Nov 21 18:05:43 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 21 Nov 2013 19:05:43 +0100 Subject: [PATCH 2/4] mgcp/rtp: Add counter for invalid RTP timestamp deltas In-Reply-To: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> This patch modifies the patch_and_count() function to check for RTP timestamp inconsistencies. It basically checks, whether dTS/dSeqNo remains constant. If this fails, the corresponding counter is incremented. There are four counter for this: Incoming and outgoing, each for streams from the BTS and the net. Note that this approach presumes, that the per RTP packet duration (in samples) remains the same throughout the entire stream. Changing the number of speech frames per channel and packet will be detected as error. In addition, the VTY command 'show mgcp' is extended by an optional 'stats' to show the counter values, too. Ticket: OW#964 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 4 ++ openbsc/src/libmgcp/mgcp_network.c | 73 +++++++++++++++++++++++++++++-- openbsc/src/libmgcp/mgcp_protocol.c | 24 ++++++++-- openbsc/src/libmgcp/mgcp_vty.c | 23 +++++++--- openbsc/tests/mgcp/mgcp_test.c | 3 +- 5 files changed, 114 insertions(+), 13 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index d5bd3dd..2ad7058 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -56,6 +56,10 @@ struct mgcp_rtp_state { int32_t timestamp_offset; uint32_t jitter; int32_t transit; + + int32_t last_tsdelta; + uint32_t err_ts_in_counter; + uint32_t err_ts_out_counter; }; struct mgcp_rtp_end { diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 2b55527..14bc024 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -143,13 +143,18 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) * we receive will be seen as a switch in streams. */ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, - int payload, struct sockaddr_in *addr, char *data, int len) + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len) { uint32_t arrival_time; int32_t transit, d; uint16_t seq, udelta; uint32_t timestamp; struct rtp_hdr *rtp_hdr; + int32_t tsdelta = 0; + int tsdelta_valid = 0; + int last_tsdelta = state->last_tsdelta; + int payload = rtp_end->payload_type; if (len < sizeof(*rtp_hdr)) return; @@ -176,6 +181,41 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", ENDPOINT_NUMBER(endp), state->ssrc, state->seq_offset, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); + } else { + /* Compute current per-packet timestamp delta */ + if (state->initialized && seq != state->max_seq) { + int corr_timestamp = state->timestamp_offset + timestamp; + tsdelta = + (int32_t)(corr_timestamp - state->last_timestamp) / + (int16_t)(seq - state->max_seq); + + if (tsdelta == 0) { + state->err_ts_in_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "Input timestamp delta is %d " + "on 0x%x SSRC: %u timestamp: %u " + "from %s:%d in %d\n", + tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } else + tsdelta_valid = 1; + } + + if (tsdelta_valid && state->last_tsdelta != tsdelta) { + if (state->last_tsdelta) { + state->err_ts_in_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "Input timestamp delta changes from %d to %d " + "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n", + state->last_tsdelta, tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } + state->last_tsdelta = tsdelta; + } } /* apply the offset and store it back to the packet */ @@ -188,6 +228,33 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s rtp_hdr->timestamp = htonl(timestamp); } + /* Check again, whether the timestamps are still valid */ + if (last_tsdelta && seq != state->max_seq) { + tsdelta = (timestamp - state->last_timestamp) / + (seq - state->max_seq); + + if (tsdelta == 0) { + state->err_ts_out_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "Output timestamp delta is %d " + "on 0x%x SSRC: %u timestamp: %u " + "from %s:%d in %d\n", + tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } else if (last_tsdelta != tsdelta) { + state->err_ts_out_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "Output timestamp delta changes from %d to %d " + "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n", + last_tsdelta, tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } + } + /* * The below takes the shape of the validation from Appendix A. Check * if there is something weird with the sequence number, otherwise check @@ -280,7 +347,7 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, if (dest == MGCP_DEST_NET) { if (is_rtp) { patch_and_count(endp, &endp->bts_state, - endp->net_end.payload_type, + &endp->net_end, addr, buf, rc); forward_data(endp->net_end.rtp.fd, &endp->taps[MGCP_TAP_NET_OUT], buf, rc); @@ -295,7 +362,7 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, } else { if (is_rtp) { patch_and_count(endp, &endp->net_state, - endp->bts_end.payload_type, + &endp->bts_end, addr, buf, rc); forward_data(endp->bts_end.rtp.fd, &endp->taps[MGCP_TAP_BTS_OUT], buf, rc); diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 616e0a9..b19b8a0 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -1163,14 +1163,30 @@ void mgcp_format_stats(struct mgcp_endpoint *endp, char *msg, size_t size) { uint32_t expected, jitter; int ploss; + int nchars; mgcp_state_calc_loss(&endp->net_state, &endp->net_end, &expected, &ploss); jitter = mgcp_state_calc_jitter(&endp->net_state); - snprintf(msg, size, "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u", - endp->bts_end.packets, endp->bts_end.octets, - endp->net_end.packets, endp->net_end.octets, - ploss, jitter); + nchars = snprintf(msg, size, + "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u", + endp->bts_end.packets, endp->bts_end.octets, + endp->net_end.packets, endp->net_end.octets, + ploss, jitter); + if (nchars < 0 || nchars >= size) + goto truncate; + + msg += nchars; + size -= nchars; + + /* Error Counter */ + snprintf(msg, size, + "\r\nX-Osmo: EC TIS=%u, TOS=%u, TIR=%u, TOR=%u", + endp->net_state.err_ts_in_counter, + endp->net_state.err_ts_out_counter, + endp->bts_state.err_ts_in_counter, + endp->bts_state.err_ts_out_counter); +truncate: msg[size - 1] = '\0'; } diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 3c239d8..528a312 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -114,7 +114,7 @@ static int config_write_mgcp(struct vty *vty) return CMD_SUCCESS; } -static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg) +static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int verbose) { int i; @@ -139,18 +139,31 @@ static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg) endp->bts_end.packets, endp->net_end.packets, endp->trans_net.packets, endp->trans_bts.packets, VTY_NEWLINE); + + if (verbose) + vty_out(vty, + " Timestamp Errs: BTS %d->%d, Net %d->%d%s", + endp->bts_state.err_ts_in_counter, + endp->bts_state.err_ts_out_counter, + endp->net_state.err_ts_in_counter, + endp->net_state.err_ts_out_counter, + VTY_NEWLINE); } } -DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", - SHOW_STR "Display information about the MGCP Media Gateway") +DEFUN(show_mcgp, show_mgcp_cmd, + "show mgcp [stats]", + SHOW_STR + "Display information about the MGCP Media Gateway\n" + "Include Statistics\n") { struct mgcp_trunk_config *trunk; + int show_stats = argc >= 1; - dump_trunk(vty, &g_cfg->trunk); + dump_trunk(vty, &g_cfg->trunk, show_stats); llist_for_each_entry(trunk, &g_cfg->trunks, entry) - dump_trunk(vty, trunk); + dump_trunk(vty, trunk, show_stats); return CMD_SUCCESS; } diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 5565e73..3499ee3 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -97,7 +97,8 @@ "C: 2\r\n" #define DLCX_RET "250 7 OK\r\n" \ - "P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n" + "P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n" \ + "X-Osmo: EC TIS=0, TOS=0, TIR=0, TOR=0\r\n" #define RQNT "RQNT 186908780 1 at mgw MGCP 1.0\r\n" \ "X: B244F267488\r\n" \ -- 1.7.9.5 From holger at freyther.de Thu Nov 21 19:30:12 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 21 Nov 2013 20:30:12 +0100 Subject: [PATCH 2/4] mgcp/rtp: Add counter for invalid RTP timestamp deltas In-Reply-To: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131121193012.GA31186@xiaoyu.lan> On Thu, Nov 21, 2013 at 07:05:43PM +0100, Jacob Erlbeck wrote: Thank you for the patch. I have one wish for you to move the code to separate method (with the side effect on the data structure). > + } else { I would prefer if we could move this code into another method and re-use it later on. Sure this requires to pass "Input"/"Output" into the function and the right counters. But I think I prefer this over the code clone. You just happened to be late to if/elseif/else and I think it is getting a bit crowded in this method. > + /* Compute current per-packet timestamp delta */ > + if (state->initialized && seq != state->max_seq) { state->initialized == TRUE in this else branc. > + int corr_timestamp = state->timestamp_offset + timestamp; > + tsdelta = > + (int32_t)(corr_timestamp - state->last_timestamp) / > + (int16_t)(seq - state->max_seq); great! > + /* Check again, whether the timestamps are still valid */ > + if (last_tsdelta && seq != state->max_seq) { seq == state->max_seq => retransmission or just the guard against the division by 0? > + tsdelta = (timestamp - state->last_timestamp) / > + (seq - state->max_seq); okay subtle change as the timestamp_offset has already been applied? My idea of taking this code out might be difficult. Can you try anyway? From jerlbeck at sysmocom.de Fri Nov 22 09:19:22 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 22 Nov 2013 10:19:22 +0100 Subject: [PATCH 2/4] mgcp/rtp: Add counter for invalid RTP timestamp deltas In-Reply-To: <20131121193012.GA31186@xiaoyu.lan> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> <20131121193012.GA31186@xiaoyu.lan> Message-ID: <528F219A.2080900@sysmocom.de> On 11/21/2013 08:30 PM, Holger Hans Peter Freyther wrote: > On Thu, Nov 21, 2013 at 07:05:43PM +0100, Jacob Erlbeck wrote: > > Thank you for the patch. I have one wish for you to move the > code to separate method (with the side effect on the data structure). Ok, see remark at the end of the mail. > >> + } else { > > I would prefer if we could move this code into another method and > re-use it later on. Sure this requires to pass "Input"/"Output" into > the function and the right counters. But I think I prefer this over > the code clone. > > You just happened to be late to if/elseif/else and I think it is > getting a bit crowded in this method. It does ;-) > > >> + /* Check again, whether the timestamps are still valid */ >> + if (last_tsdelta && seq != state->max_seq) { > > seq == state->max_seq => retransmission or just the guard against > the division by 0? The latter, but dSeqNo == 0 => dTS == 0 should be checked, too. > > >> + tsdelta = (timestamp - state->last_timestamp) / >> + (seq - state->max_seq); > > okay subtle change as the timestamp_offset has already been applied? My > idea of taking this code out might be difficult. Can you try anyway? Yes, I didn't find a clean solution without code duplication yesterday. But I think it should be possible by moving this into a separate function which does checking and tsdelta computation. This makes it easier to improve the tests (e.g. the dSeqNo check above or more complex packet duration stuff) and should help to clean up mgcp_patch_and_count, too. I'll update the patch accordingly. Jacob From jerlbeck at sysmocom.de Fri Nov 22 09:45:55 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 22 Nov 2013 10:45:55 +0100 Subject: [PATCH 2/4] mgcp/rtp: Add counter for invalid RTP timestamp deltas In-Reply-To: <20131121193012.GA31186@xiaoyu.lan> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> <20131121193012.GA31186@xiaoyu.lan> Message-ID: <528F27D3.8030101@sysmocom.de> On 11/21/2013 08:30 PM, Holger Hans Peter Freyther wrote: > On Thu, Nov 21, 2013 at 07:05:43PM +0100, Jacob Erlbeck wrote: > > Thank you for the patch. I have one wish for you to move the > code to separate method (with the side effect on the data structure). I also would like to have global mgcp (or per trunk) summary counters (the same 4 values), preferably as rate counters. But I'd rather put that into another patch. Jacob From jerlbeck at sysmocom.de Mon Nov 25 11:53:28 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 25 Nov 2013 12:53:28 +0100 Subject: [PATCH 1/3] mgcp/rtp: Add counter for invalid RTP timestamp deltas In-Reply-To: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385380410-23671-1-git-send-email-jerlbeck@sysmocom.de> This patch modifies the patch_and_count() function to check for RTP timestamp inconsistencies. It basically checks, whether dTS/dSeqNo remains constant. If this fails, the corresponding counter is incremented. There are four counter for this: Incoming and outgoing, each for streams from the BTS and the net. Note that this approach presumes, that the per RTP packet duration (in samples) remains the same throughout the entire stream. Changing the number of speech frames per channel and packet will be detected as error. In addition, the VTY command 'show mgcp' is extended by an optional 'stats' to show the counter values, too. Ticket: OW#964 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 14 +++- openbsc/src/libmgcp/mgcp_network.c | 126 ++++++++++++++++++++++++++----- openbsc/src/libmgcp/mgcp_protocol.c | 24 +++++- openbsc/src/libmgcp/mgcp_vty.c | 23 ++++-- openbsc/tests/mgcp/mgcp_test.c | 5 +- 5 files changed, 160 insertions(+), 32 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index d5bd3dd..8b6a56b 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -40,22 +40,30 @@ enum mgcp_trunk_type { MGCP_TRUNK_E1, }; +struct mgcp_rtp_stream_state { + uint32_t ssrc; + uint16_t last_seq; + uint32_t last_timestamp; + uint32_t err_ts_counter; + int32_t last_tsdelta; +}; + struct mgcp_rtp_state { int initialized; int patch; uint32_t orig_ssrc; - uint32_t ssrc; uint16_t base_seq; - uint16_t max_seq; int seq_offset; int cycles; - uint32_t last_timestamp; int32_t timestamp_offset; uint32_t jitter; int32_t transit; + + struct mgcp_rtp_stream_state in_stream; + struct mgcp_rtp_stream_state out_stream; }; struct mgcp_rtp_end { diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 2b55527..ba84956 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -134,6 +134,73 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) endp->net_end.rtp_port, buf, 1); } +static int check_rtp_timestamp(struct mgcp_endpoint *endp, + struct mgcp_rtp_stream_state *state, + struct mgcp_rtp_end *rtp_end, + struct sockaddr_in *addr, + uint16_t seq, uint32_t timestamp, + const char *text, int32_t *tsdelta_out) +{ + int32_t tsdelta; + + if (state->last_tsdelta == 0 && timestamp == state->last_timestamp) + /* Not fully intialized, skip */ + return 0; + + if (seq == state->last_seq) { + if (timestamp != state->last_timestamp) { + state->err_ts_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "The %s timestamp delta is != 0 but the sequence " + "number %d is the same" + "on 0x%x SSRC: %u timestamp: %u " + "from %s:%d in %d\n", + text, seq, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } + return 0; + } + + tsdelta = + (int32_t)(timestamp - state->last_timestamp) / + (int16_t)(seq - state->last_seq); + + if (tsdelta == 0) { + state->err_ts_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "The %s timestamp delta is %d " + "on 0x%x SSRC: %u timestamp: %u " + "from %s:%d in %d\n", + text, tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + + return 0; + } + + if (state->last_tsdelta != tsdelta) { + if (state->last_tsdelta) { + state->err_ts_counter += 1; + LOGP(DMGCP, LOGL_ERROR, + "The %s timestamp delta changes from %d to %d " + "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n", + text, state->last_tsdelta, tsdelta, + ENDPOINT_NUMBER(endp), state->ssrc, timestamp, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); + } + } + + if (tsdelta_out) + *tsdelta_out = tsdelta; + + return 1; +} + + /** * The RFC 3550 Appendix A assumes there are multiple sources but * some of the supported endpoints (e.g. the nanoBTS) can only handle @@ -143,13 +210,15 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) * we receive will be seen as a switch in streams. */ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, - int payload, struct sockaddr_in *addr, char *data, int len) + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len) { uint32_t arrival_time; int32_t transit, d; uint16_t seq, udelta; uint32_t timestamp; struct rtp_hdr *rtp_hdr; + int payload = rtp_end->payload_type; if (len < sizeof(*rtp_hdr)) return; @@ -160,24 +229,37 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s arrival_time = get_current_ts(); if (!state->initialized) { + state->in_stream.last_seq = seq - 1; + state->in_stream.ssrc = state->orig_ssrc = rtp_hdr->ssrc; + state->in_stream.last_tsdelta = 0; state->base_seq = seq; - state->max_seq = seq - 1; - state->ssrc = state->orig_ssrc = rtp_hdr->ssrc; state->initialized = 1; - state->last_timestamp = timestamp; state->jitter = 0; state->transit = arrival_time - timestamp; - } else if (state->ssrc != rtp_hdr->ssrc) { - state->ssrc = rtp_hdr->ssrc; - state->seq_offset = (state->max_seq + 1) - seq; - state->timestamp_offset = state->last_timestamp - timestamp; + state->out_stream = state->in_stream; + } else if (state->in_stream.ssrc != rtp_hdr->ssrc) { + state->in_stream.ssrc = rtp_hdr->ssrc; + state->seq_offset = (state->out_stream.last_seq + 1) - seq; + state->timestamp_offset = state->out_stream.last_timestamp - timestamp; state->patch = endp->allow_patch; LOGP(DMGCP, LOGL_NOTICE, "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", - ENDPOINT_NUMBER(endp), state->ssrc, state->seq_offset, - inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); + ENDPOINT_NUMBER(endp), state->in_stream.ssrc, + state->seq_offset, inet_ntoa(addr->sin_addr), + ntohs(addr->sin_port), endp->conn_mode); + + state->in_stream.last_tsdelta = 0; + } else { + /* Compute current per-packet timestamp delta */ + check_rtp_timestamp(endp, &state->in_stream, rtp_end, addr, + seq, timestamp, "input", + &state->in_stream.last_tsdelta); } + /* Save before patching */ + state->in_stream.last_timestamp = timestamp; + state->in_stream.last_seq = seq; + /* apply the offset and store it back to the packet */ if (state->patch) { seq += state->seq_offset; @@ -188,14 +270,21 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s rtp_hdr->timestamp = htonl(timestamp); } + /* Check again, whether the timestamps are still valid */ + check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr, + seq, timestamp, "output", + &state->out_stream.last_tsdelta); + /* * The below takes the shape of the validation from Appendix A. Check * if there is something weird with the sequence number, otherwise check * for a wrap around in the sequence number. + * + * Note that last_seq is used where the appendix mentions max_seq. */ - udelta = seq - state->max_seq; + udelta = seq - state->out_stream.last_seq; if (udelta < RTP_MAX_DROPOUT) { - if (seq < state->max_seq) + if (seq < state->out_stream.last_seq) state->cycles += RTP_SEQ_MOD; } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) { LOGP(DMGCP, LOGL_NOTICE, @@ -215,9 +304,10 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s d = -d; state->jitter += d - ((state->jitter + 8) >> 4); - - state->max_seq = seq; - state->last_timestamp = timestamp; + /* Save output values */ + state->out_stream.last_seq = seq; + state->out_stream.last_timestamp = timestamp; + state->out_stream.ssrc = rtp_hdr->ssrc; if (payload < 0) return; @@ -280,7 +370,7 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, if (dest == MGCP_DEST_NET) { if (is_rtp) { patch_and_count(endp, &endp->bts_state, - endp->net_end.payload_type, + &endp->net_end, addr, buf, rc); forward_data(endp->net_end.rtp.fd, &endp->taps[MGCP_TAP_NET_OUT], buf, rc); @@ -295,7 +385,7 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, } else { if (is_rtp) { patch_and_count(endp, &endp->net_state, - endp->bts_end.payload_type, + &endp->bts_end, addr, buf, rc); forward_data(endp->bts_end.rtp.fd, &endp->taps[MGCP_TAP_BTS_OUT], buf, rc); @@ -684,7 +774,7 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *state, struct mgcp_rtp_end *end, uint32_t *expected, int *loss) { - *expected = state->cycles + state->max_seq; + *expected = state->cycles + state->out_stream.last_seq; *expected = *expected - state->base_seq + 1; if (!state->initialized) { diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 616e0a9..6d22cf3 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -1163,14 +1163,30 @@ void mgcp_format_stats(struct mgcp_endpoint *endp, char *msg, size_t size) { uint32_t expected, jitter; int ploss; + int nchars; mgcp_state_calc_loss(&endp->net_state, &endp->net_end, &expected, &ploss); jitter = mgcp_state_calc_jitter(&endp->net_state); - snprintf(msg, size, "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u", - endp->bts_end.packets, endp->bts_end.octets, - endp->net_end.packets, endp->net_end.octets, - ploss, jitter); + nchars = snprintf(msg, size, + "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u", + endp->bts_end.packets, endp->bts_end.octets, + endp->net_end.packets, endp->net_end.octets, + ploss, jitter); + if (nchars < 0 || nchars >= size) + goto truncate; + + msg += nchars; + size -= nchars; + + /* Error Counter */ + snprintf(msg, size, + "\r\nX-Osmo: EC TIS=%u, TOS=%u, TIR=%u, TOR=%u", + endp->net_state.in_stream.err_ts_counter, + endp->net_state.out_stream.err_ts_counter, + endp->bts_state.in_stream.err_ts_counter, + endp->bts_state.out_stream.err_ts_counter); +truncate: msg[size - 1] = '\0'; } diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c index 3c239d8..5aeb393 100644 --- a/openbsc/src/libmgcp/mgcp_vty.c +++ b/openbsc/src/libmgcp/mgcp_vty.c @@ -114,7 +114,7 @@ static int config_write_mgcp(struct vty *vty) return CMD_SUCCESS; } -static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg) +static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int verbose) { int i; @@ -139,18 +139,31 @@ static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg) endp->bts_end.packets, endp->net_end.packets, endp->trans_net.packets, endp->trans_bts.packets, VTY_NEWLINE); + + if (verbose) + vty_out(vty, + " Timestamp Errs: BTS %d->%d, Net %d->%d%s", + endp->bts_state.in_stream.err_ts_counter, + endp->bts_state.out_stream.err_ts_counter, + endp->net_state.in_stream.err_ts_counter, + endp->net_state.out_stream.err_ts_counter, + VTY_NEWLINE); } } -DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", - SHOW_STR "Display information about the MGCP Media Gateway") +DEFUN(show_mcgp, show_mgcp_cmd, + "show mgcp [stats]", + SHOW_STR + "Display information about the MGCP Media Gateway\n" + "Include Statistics\n") { struct mgcp_trunk_config *trunk; + int show_stats = argc >= 1; - dump_trunk(vty, &g_cfg->trunk); + dump_trunk(vty, &g_cfg->trunk, show_stats); llist_for_each_entry(trunk, &g_cfg->trunks, entry) - dump_trunk(vty, trunk); + dump_trunk(vty, trunk, show_stats); return CMD_SUCCESS; } diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 5565e73..e5e6245 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -97,7 +97,8 @@ "C: 2\r\n" #define DLCX_RET "250 7 OK\r\n" \ - "P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n" + "P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n" \ + "X-Osmo: EC TIS=0, TOS=0, TIR=0, TOR=0\r\n" #define RQNT "RQNT 186908780 1 at mgw MGCP 1.0\r\n" \ "X: B244F267488\r\n" \ @@ -309,7 +310,7 @@ static void test_packet_loss_calc(void) state.initialized = 1; state.base_seq = pl_test_dat[i].base_seq; - state.max_seq = pl_test_dat[i].max_seq; + state.out_stream.last_seq = pl_test_dat[i].max_seq; state.cycles = pl_test_dat[i].cycles; rtp.packets = pl_test_dat[i].packets; -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 25 11:53:29 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 25 Nov 2013 12:53:29 +0100 Subject: [PATCH 2/3] mgcp/rtp: Add test case for RTP timestamp patching and stats In-Reply-To: <1385380410-23671-1-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> <1385380410-23671-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385380410-23671-2-git-send-email-jerlbeck@sysmocom.de> This patch adds a test case to check, whether RTP timestamps are generated properly after SSRC changes and whether the error counters work properly. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 18 +++--- openbsc/tests/mgcp/mgcp_test.c | 106 ++++++++++++++++++++++++++++++++++++ openbsc/tests/mgcp/mgcp_test.ok | 16 ++++++ 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index ba84956..fa10cec 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -209,9 +209,9 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp, * There is also no probation period for new sources. Every package * we receive will be seen as a switch in streams. */ -static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, - struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, - char *data, int len) +void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len) { uint32_t arrival_time; int32_t transit, d; @@ -369,9 +369,9 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, if (dest == MGCP_DEST_NET) { if (is_rtp) { - patch_and_count(endp, &endp->bts_state, - &endp->net_end, - addr, buf, rc); + 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, @@ -384,9 +384,9 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, } } else { if (is_rtp) { - patch_and_count(endp, &endp->net_state, - &endp->bts_end, - addr, buf, rc); + 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, diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index e5e6245..d3c5687 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -348,6 +348,111 @@ static void test_mgcp_stats(void) msgb_free(msg); } +struct rtp_packet_info { + float txtime; + int len; + char *data; +}; + +struct rtp_packet_info test_rtp_packets1[] = { + /* RTP: SeqNo=0, TS=0 */ + {0.000000, 20, "\x80\x62\x00\x00\x00\x00\x00\x00\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=1, TS=160 */ + {0.020000, 20, "\x80\x62\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=2, TS=320 */ + {0.040000, 20, "\x80\x62\x00\x02\x00\x00\x01\x40\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Repeat RTP timestamp: */ + /* RTP: SeqNo=3, TS=320 */ + {0.060000, 20, "\x80\x62\x00\x03\x00\x00\x01\x40\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=4, TS=480 */ + {0.080000, 20, "\x80\x62\x00\x04\x00\x00\x01\xE0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=5, TS=640 */ + {0.100000, 20, "\x80\x62\x00\x05\x00\x00\x02\x80\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Double skip RTP timestamp (delta = 2*160): */ + /* RTP: SeqNo=6, TS=960 */ + {0.120000, 20, "\x80\x62\x00\x06\x00\x00\x03\xC0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=7, TS=1120 */ + {0.140000, 20, "\x80\x62\x00\x07\x00\x00\x04\x60\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=8, TS=1280 */ + {0.160000, 20, "\x80\x62\x00\x08\x00\x00\x05\x00\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Non 20ms RTP timestamp (delta = 120): */ + /* RTP: SeqNo=9, TS=1400 */ + {0.180000, 20, "\x80\x62\x00\x09\x00\x00\x05\x78\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=10, TS=1560 */ + {0.200000, 20, "\x80\x62\x00\x0A\x00\x00\x06\x18\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=11, TS=1720 */ + {0.220000, 20, "\x80\x62\x00\x0B\x00\x00\x06\xB8\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* SSRC changed to 0x10203040, RTP timestamp jump */ + /* RTP: SeqNo=12, TS=34688 */ + {0.240000, 20, "\x80\x62\x00\x0C\x00\x00\x87\x80\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=13, TS=34848 */ + {0.260000, 20, "\x80\x62\x00\x0D\x00\x00\x88\x20\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=14, TS=35008 */ + {0.280000, 20, "\x80\x62\x00\x0E\x00\x00\x88\xC0\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, +}; + +void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len); + +static void test_packet_error_detection(void) +{ + int i; + + struct mgcp_trunk_config trunk; + struct mgcp_endpoint endp; + struct mgcp_rtp_state state; + struct mgcp_rtp_end rtp; + struct sockaddr_in addr = {0}; + char buffer[4096]; + + printf("Testing packet error detection.\n"); + + memset(&trunk, 0, sizeof(trunk)); + memset(&endp, 0, sizeof(endp)); + memset(&state, 0, sizeof(state)); + memset(&rtp, 0, sizeof(rtp)); + + trunk.number_endpoints = 1; + trunk.endpoints = &endp; + + rtp.payload_type = 98; + endp.allow_patch = 1; + endp.tcfg = &trunk; + + for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { + struct rtp_packet_info *info = test_rtp_packets1 + i; + + OSMO_ASSERT(info->len <= sizeof(buffer)); + OSMO_ASSERT(info->len >= 0); + memmove(buffer, info->data, info->len); + + mgcp_patch_and_count(&endp, &state, &rtp, &addr, + buffer, info->len); + + printf("TS: %d, dTS: %d, TS Errs: in %d, out %d\n", + state.out_stream.last_timestamp, + state.out_stream.last_tsdelta, + state.in_stream.err_ts_counter, + state.out_stream.err_ts_counter); + } +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); @@ -357,6 +462,7 @@ int main(int argc, char **argv) test_packet_loss_calc(); test_rqnt_cb(); test_mgcp_stats(); + test_packet_error_detection(); printf("Done\n"); return EXIT_SUCCESS; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8711e38..8c3fa26 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -28,4 +28,20 @@ Testing packet loss calculation. Testing stat parsing Parsing result: 0 Parsing result: 0 +Testing packet error detection. +TS: 0, dTS: 0, TS Errs: in 0, out 0 +TS: 160, dTS: 160, TS Errs: in 0, out 0 +TS: 320, dTS: 160, TS Errs: in 0, out 0 +TS: 320, dTS: 160, TS Errs: in 1, out 1 +TS: 480, dTS: 160, TS Errs: in 1, out 1 +TS: 640, dTS: 160, TS Errs: in 1, out 1 +TS: 960, dTS: 320, TS Errs: in 2, out 2 +TS: 1120, dTS: 160, TS Errs: in 3, out 3 +TS: 1280, dTS: 160, TS Errs: in 3, out 3 +TS: 1400, dTS: 120, TS Errs: in 4, out 4 +TS: 1560, dTS: 160, TS Errs: in 5, out 5 +TS: 1720, dTS: 160, TS Errs: in 5, out 5 +TS: 1720, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 6 +TS: 2040, dTS: 160, TS Errs: in 5, out 6 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 25 11:53:30 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 25 Nov 2013 12:53:30 +0100 Subject: [PATCH 3/3] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <1385380410-23671-1-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-2-git-send-email-jerlbeck@sysmocom.de> <1385380410-23671-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385380410-23671-3-git-send-email-jerlbeck@sysmocom.de> The current implementation increments the seqno but does not increment the RTP timestamp, leading to two identical timestamps following one after the other. This patch fixes this by adding the computed tsdelta when the offset is calulated. In the unlikely case, that a tsdelta hasn't been computed yet when the SSRC changes, a tsdelta is computed based on the RTP rate and a RTP packet duration of 20ms (one speech frame per channel and packet). If the RTP rate is not known, a rate of 8000 is assumed. Note that this approach presumes, that the per RTP packet duration (in samples) is the same for the last two packets of the stream being replaced (the first one). Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 5 +++++ openbsc/src/libmgcp/mgcp_network.c | 24 +++++++++++++++++++----- openbsc/src/libmgcp/mgcp_protocol.c | 14 +++++++++++++- openbsc/tests/mgcp/mgcp_test.c | 2 ++ openbsc/tests/mgcp/mgcp_test.ok | 6 +++--- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 8b6a56b..c581c24 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -77,6 +77,10 @@ struct mgcp_rtp_end { /* per endpoint data */ int payload_type; + uint32_t rate; + uint32_t frame_duration_num; + uint32_t frame_duration_den; + int frames_per_packet; char *fmtp_extra; /* @@ -176,5 +180,6 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *, uint32_t *expected, int *loss); uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *); +void mgcp_rtp_end_init(struct mgcp_rtp_end *end); #endif diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index fa10cec..2fd9a80 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -78,7 +78,6 @@ struct rtp_hdr { #define RTP_MAX_DROPOUT 3000 #define RTP_MAX_MISORDER 100 - enum { MGCP_DEST_NET = 0, MGCP_DEST_BTS, @@ -238,15 +237,30 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->transit = arrival_time - timestamp; state->out_stream = state->in_stream; } else if (state->in_stream.ssrc != rtp_hdr->ssrc) { + int32_t tsdelta = state->out_stream.last_tsdelta; + if (tsdelta != 0) { + tsdelta = rtp_end->rate * rtp_end->frames_per_packet * + rtp_end->frame_duration_num / + rtp_end->frame_duration_den; + LOGP(DMGCP, LOGL_NOTICE, + "Computed timestamp delta %d based on " + "rate %d, num frames %d, frame duration %d/%d\n", + tsdelta, rtp_end->rate, rtp_end->frames_per_packet, + rtp_end->frame_duration_num, + rtp_end->frame_duration_den); + } state->in_stream.ssrc = rtp_hdr->ssrc; state->seq_offset = (state->out_stream.last_seq + 1) - seq; - state->timestamp_offset = state->out_stream.last_timestamp - timestamp; + state->timestamp_offset = + (state->out_stream.last_timestamp + tsdelta) - timestamp; state->patch = endp->allow_patch; LOGP(DMGCP, LOGL_NOTICE, - "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", + "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d " + "from %s:%d in %d\n", ENDPOINT_NUMBER(endp), state->in_stream.ssrc, - state->seq_offset, inet_ntoa(addr->sin_addr), - ntohs(addr->sin_port), endp->conn_mode); + state->seq_offset, tsdelta, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); state->in_stream.last_tsdelta = 0; } else { diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 6d22cf3..ef1b666 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -40,6 +40,12 @@ for (line = strtok_r(NULL, "\r\n", &save); line;\ line = strtok_r(NULL, "\r\n", &save)) +/* Assume audio frame length of 20ms */ +#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20 +#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 +#define DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET 1 +#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000 + static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end); struct mgcp_parse_data { @@ -967,11 +973,17 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->fmtp_extra = NULL; } -static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) +void mgcp_rtp_end_init(struct mgcp_rtp_end *end) { mgcp_rtp_end_reset(end); end->rtp.fd = -1; end->rtcp.fd = -1; + + /* Set default values */ + end->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM; + end->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN; + end->frames_per_packet = DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET; + end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; } int mgcp_endpoints_allocate(struct mgcp_trunk_config *tcfg) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index d3c5687..b25619f 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -428,6 +428,8 @@ static void test_packet_error_detection(void) memset(&state, 0, sizeof(state)); memset(&rtp, 0, sizeof(rtp)); + mgcp_rtp_end_init(&rtp); + trunk.number_endpoints = 1; trunk.endpoints = &endp; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8c3fa26..5666424 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -41,7 +41,7 @@ TS: 1280, dTS: 160, TS Errs: in 3, out 3 TS: 1400, dTS: 120, TS Errs: in 4, out 4 TS: 1560, dTS: 160, TS Errs: in 5, out 5 TS: 1720, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 6 -TS: 1880, dTS: 160, TS Errs: in 5, out 6 -TS: 2040, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 5 +TS: 2040, dTS: 160, TS Errs: in 5, out 5 +TS: 2200, dTS: 160, TS Errs: in 5, out 5 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 25 14:23:35 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 25 Nov 2013 15:23:35 +0100 Subject: [PATCH] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <1385380410-23671-3-git-send-email-jerlbeck@sysmocom.de> References: <1385380410-23671-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385389415-18120-1-git-send-email-jerlbeck@sysmocom.de> The current implementation increments the seqno but does not increment the RTP timestamp, leading to two identical timestamps following one after the other. This patch fixes this by adding the computed tsdelta when the offset is calulated. In the unlikely case, that a tsdelta hasn't been computed yet when the SSRC changes, a tsdelta is computed based on the RTP rate and a RTP packet duration of 20ms (one speech frame per channel and packet). If the RTP rate is not known, a rate of 8000 is assumed. Note that this approach presumes, that the per RTP packet duration (in samples) is the same for the last two packets of the stream being replaced (the first one). Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 4 ++++ openbsc/src/libmgcp/mgcp_network.c | 23 +++++++++++++++++++---- openbsc/src/libmgcp/mgcp_protocol.c | 12 ++++++++++++ openbsc/tests/mgcp/mgcp_test.c | 16 +++++++++++----- openbsc/tests/mgcp/mgcp_test.ok | 6 +++--- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 8b6a56b..0b52c1c 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -77,6 +77,10 @@ struct mgcp_rtp_end { /* per endpoint data */ int payload_type; + uint32_t rate; + uint32_t frame_duration_num; + uint32_t frame_duration_den; + int frames_per_packet; char *fmtp_extra; /* diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index fa10cec..8f7fd09 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -238,15 +238,30 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->transit = arrival_time - timestamp; state->out_stream = state->in_stream; } else if (state->in_stream.ssrc != rtp_hdr->ssrc) { + int32_t tsdelta = state->out_stream.last_tsdelta; + if (tsdelta != 0) { + tsdelta = rtp_end->rate * rtp_end->frames_per_packet * + rtp_end->frame_duration_num / + rtp_end->frame_duration_den; + LOGP(DMGCP, LOGL_NOTICE, + "Computed timestamp delta %d based on " + "rate %d, num frames %d, frame duration %d/%d\n", + tsdelta, rtp_end->rate, rtp_end->frames_per_packet, + rtp_end->frame_duration_num, + rtp_end->frame_duration_den); + } state->in_stream.ssrc = rtp_hdr->ssrc; state->seq_offset = (state->out_stream.last_seq + 1) - seq; - state->timestamp_offset = state->out_stream.last_timestamp - timestamp; + state->timestamp_offset = + (state->out_stream.last_timestamp + tsdelta) - timestamp; state->patch = endp->allow_patch; LOGP(DMGCP, LOGL_NOTICE, - "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", + "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d " + "from %s:%d in %d\n", ENDPOINT_NUMBER(endp), state->in_stream.ssrc, - state->seq_offset, inet_ntoa(addr->sin_addr), - ntohs(addr->sin_port), endp->conn_mode); + state->seq_offset, tsdelta, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); state->in_stream.last_tsdelta = 0; } else { diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 6d22cf3..71fb89d 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -40,6 +40,12 @@ for (line = strtok_r(NULL, "\r\n", &save); line;\ line = strtok_r(NULL, "\r\n", &save)) +/* Assume audio frame length of 20ms */ +#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20 +#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 +#define DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET 1 +#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000 + static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end); struct mgcp_parse_data { @@ -965,6 +971,12 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->local_alloc = -1; talloc_free(end->fmtp_extra); end->fmtp_extra = NULL; + + /* Set default values */ + end->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM; + end->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN; + end->frames_per_packet = DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET; + end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; } static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index d3c5687..84c55aa 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -417,7 +417,7 @@ static void test_packet_error_detection(void) struct mgcp_trunk_config trunk; struct mgcp_endpoint endp; struct mgcp_rtp_state state; - struct mgcp_rtp_end rtp; + struct mgcp_rtp_end *rtp = &endp.net_end; struct sockaddr_in addr = {0}; char buffer[4096]; @@ -426,14 +426,20 @@ static void test_packet_error_detection(void) memset(&trunk, 0, sizeof(trunk)); memset(&endp, 0, sizeof(endp)); memset(&state, 0, sizeof(state)); - memset(&rtp, 0, sizeof(rtp)); trunk.number_endpoints = 1; trunk.endpoints = &endp; + endp.tcfg = &trunk; + + /* This doesn't free endp but resets/frees all fields of the structure + * and invokes mgcp_rtp_end_reset() for each mgcp_rtp_end. OTOH, it + * expects valid pointer fields (either NULL or talloc'ed), so the + * memset is still needed. It also requires that endp.tcfg and + * trunk.endpoints are set up properly. */ + mgcp_free_endp(&endp); - rtp.payload_type = 98; + rtp->payload_type = 98; endp.allow_patch = 1; - endp.tcfg = &trunk; for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { struct rtp_packet_info *info = test_rtp_packets1 + i; @@ -442,7 +448,7 @@ static void test_packet_error_detection(void) OSMO_ASSERT(info->len >= 0); memmove(buffer, info->data, info->len); - mgcp_patch_and_count(&endp, &state, &rtp, &addr, + mgcp_patch_and_count(&endp, &state, rtp, &addr, buffer, info->len); printf("TS: %d, dTS: %d, TS Errs: in %d, out %d\n", diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8c3fa26..5666424 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -41,7 +41,7 @@ TS: 1280, dTS: 160, TS Errs: in 3, out 3 TS: 1400, dTS: 120, TS Errs: in 4, out 4 TS: 1560, dTS: 160, TS Errs: in 5, out 5 TS: 1720, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 6 -TS: 1880, dTS: 160, TS Errs: in 5, out 6 -TS: 2040, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 5 +TS: 2040, dTS: 160, TS Errs: in 5, out 5 +TS: 2200, dTS: 160, TS Errs: in 5, out 5 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Nov 21 18:05:44 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 21 Nov 2013 19:05:44 +0100 Subject: [PATCH 3/4] mgcp/rtp: Add test case for RTP timestamp patching and stats In-Reply-To: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385057145-26881-3-git-send-email-jerlbeck@sysmocom.de> This patch adds a test case to check, whether RTP timestamps are generated properly after SSRC changes and whether the error counters work properly. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 18 +++--- openbsc/tests/mgcp/mgcp_test.c | 106 ++++++++++++++++++++++++++++++++++++ openbsc/tests/mgcp/mgcp_test.ok | 16 ++++++ 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 14bc024..17e3d87 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -142,9 +142,9 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp) * There is also no probation period for new sources. Every package * we receive will be seen as a switch in streams. */ -static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, - struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, - char *data, int len) +void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len) { uint32_t arrival_time; int32_t transit, d; @@ -346,9 +346,9 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, if (dest == MGCP_DEST_NET) { if (is_rtp) { - patch_and_count(endp, &endp->bts_state, - &endp->net_end, - addr, buf, rc); + 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, @@ -361,9 +361,9 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, } } else { if (is_rtp) { - patch_and_count(endp, &endp->net_state, - &endp->bts_end, - addr, buf, rc); + 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, diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 3499ee3..705db80 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -348,6 +348,111 @@ static void test_mgcp_stats(void) msgb_free(msg); } +struct rtp_packet_info { + float txtime; + int len; + char *data; +}; + +struct rtp_packet_info test_rtp_packets1[] = { + /* RTP: SeqNo=0, TS=0 */ + {0.000000, 20, "\x80\x62\x00\x00\x00\x00\x00\x00\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=1, TS=160 */ + {0.020000, 20, "\x80\x62\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=2, TS=320 */ + {0.040000, 20, "\x80\x62\x00\x02\x00\x00\x01\x40\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Repeat RTP timestamp: */ + /* RTP: SeqNo=3, TS=320 */ + {0.060000, 20, "\x80\x62\x00\x03\x00\x00\x01\x40\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=4, TS=480 */ + {0.080000, 20, "\x80\x62\x00\x04\x00\x00\x01\xE0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=5, TS=640 */ + {0.100000, 20, "\x80\x62\x00\x05\x00\x00\x02\x80\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Double skip RTP timestamp (delta = 2*160): */ + /* RTP: SeqNo=6, TS=960 */ + {0.120000, 20, "\x80\x62\x00\x06\x00\x00\x03\xC0\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=7, TS=1120 */ + {0.140000, 20, "\x80\x62\x00\x07\x00\x00\x04\x60\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=8, TS=1280 */ + {0.160000, 20, "\x80\x62\x00\x08\x00\x00\x05\x00\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* Non 20ms RTP timestamp (delta = 120): */ + /* RTP: SeqNo=9, TS=1400 */ + {0.180000, 20, "\x80\x62\x00\x09\x00\x00\x05\x78\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=10, TS=1560 */ + {0.200000, 20, "\x80\x62\x00\x0A\x00\x00\x06\x18\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=11, TS=1720 */ + {0.220000, 20, "\x80\x62\x00\x0B\x00\x00\x06\xB8\x11\x22\x33\x44" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* SSRC changed to 0x10203040, RTP timestamp jump */ + /* RTP: SeqNo=12, TS=34688 */ + {0.240000, 20, "\x80\x62\x00\x0C\x00\x00\x87\x80\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=13, TS=34848 */ + {0.260000, 20, "\x80\x62\x00\x0D\x00\x00\x88\x20\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, + /* RTP: SeqNo=14, TS=35008 */ + {0.280000, 20, "\x80\x62\x00\x0E\x00\x00\x88\xC0\x10\x20\x30\x40" + "\x01\x23\x45\x67\x89\xAB\xCD\xEF"}, +}; + +void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state, + struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr, + char *data, int len); + +static void test_packet_error_detection(void) +{ + int i; + + struct mgcp_trunk_config trunk; + struct mgcp_endpoint endp; + struct mgcp_rtp_state state; + struct mgcp_rtp_end rtp; + struct sockaddr_in addr = {0}; + char buffer[4096]; + + printf("Testing packet error detection.\n"); + + memset(&trunk, 0, sizeof(trunk)); + memset(&endp, 0, sizeof(endp)); + memset(&state, 0, sizeof(state)); + memset(&rtp, 0, sizeof(rtp)); + + trunk.number_endpoints = 1; + trunk.endpoints = &endp; + + rtp.payload_type = 98; + endp.allow_patch = 1; + endp.tcfg = &trunk; + + for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { + struct rtp_packet_info *info = test_rtp_packets1 + i; + + OSMO_ASSERT(info->len <= sizeof(buffer)); + OSMO_ASSERT(info->len >= 0); + memmove(buffer, info->data, info->len); + + mgcp_patch_and_count(&endp, &state, &rtp, &addr, + buffer, info->len); + + printf("TS: %d, dTS: %d, TS Errs: in %d, out %d\n", + state.last_timestamp, + state.last_tsdelta, + state.err_ts_in_counter, + state.err_ts_out_counter); + } +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); @@ -357,6 +462,7 @@ int main(int argc, char **argv) test_packet_loss_calc(); test_rqnt_cb(); test_mgcp_stats(); + test_packet_error_detection(); printf("Done\n"); return EXIT_SUCCESS; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8711e38..8c3fa26 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -28,4 +28,20 @@ Testing packet loss calculation. Testing stat parsing Parsing result: 0 Parsing result: 0 +Testing packet error detection. +TS: 0, dTS: 0, TS Errs: in 0, out 0 +TS: 160, dTS: 160, TS Errs: in 0, out 0 +TS: 320, dTS: 160, TS Errs: in 0, out 0 +TS: 320, dTS: 160, TS Errs: in 1, out 1 +TS: 480, dTS: 160, TS Errs: in 1, out 1 +TS: 640, dTS: 160, TS Errs: in 1, out 1 +TS: 960, dTS: 320, TS Errs: in 2, out 2 +TS: 1120, dTS: 160, TS Errs: in 3, out 3 +TS: 1280, dTS: 160, TS Errs: in 3, out 3 +TS: 1400, dTS: 120, TS Errs: in 4, out 4 +TS: 1560, dTS: 160, TS Errs: in 5, out 5 +TS: 1720, dTS: 160, TS Errs: in 5, out 5 +TS: 1720, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 6 +TS: 2040, dTS: 160, TS Errs: in 5, out 6 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Nov 21 18:05:45 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 21 Nov 2013 19:05:45 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> The current implementation increments the seqno but does not increment the RTP timestamp, leading to two identical timestamps following one after the other. This patch fixes this by adding the computed tsdelta when the offset is calulated. In the unlikely case, that a tsdelta hasn't been computed yet when the SSRC changes, a tsdelta is computed based on the RTP rate and a RTP packet duration of 20ms (one speech frame per channel and packet). If the RTP rate is not known, a rate of 8000 is assumed. Note that this approach presumes, that the per RTP packet duration (in samples) is the same for the last two packets of the stream being replaced (the first one). Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 1 + openbsc/src/libmgcp/mgcp_network.c | 33 ++++++++++++++++++++++++++++--- openbsc/tests/mgcp/mgcp_test.ok | 6 +++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 2ad7058..b9bff53 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -73,6 +73,7 @@ struct mgcp_rtp_end { /* per endpoint data */ int payload_type; + uint32_t rate; char *fmtp_extra; /* diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 17e3d87..2ac873e 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -78,6 +78,10 @@ struct rtp_hdr { #define RTP_MAX_DROPOUT 3000 #define RTP_MAX_MISORDER 100 +/* Assume audio frame length of 20ms */ +#define RTP_AUDIO_FRAME_DUR_NUM 20 +#define RTP_AUDIO_FRAME_DUR_DEN 1000 +#define RTP_AUDIO_DEFAULT_RATE 8000 enum { MGCP_DEST_NET = 0, @@ -173,14 +177,37 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->jitter = 0; state->transit = arrival_time - timestamp; } else if (state->ssrc != rtp_hdr->ssrc) { + tsdelta = state->last_tsdelta; + tsdelta_valid = tsdelta != 0; + if (!tsdelta_valid) { + int rate = rtp_end->rate; + if (!rate) { + rate = RTP_AUDIO_DEFAULT_RATE; + LOGP(DMGCP, LOGL_NOTICE, + "Using default RTP rate %d which might be " + "different from the rate contained in the " + "SDP data.\n", + rate + ); + } + tsdelta = rate * RTP_AUDIO_FRAME_DUR_NUM / + RTP_AUDIO_FRAME_DUR_DEN; + state->last_tsdelta = tsdelta; + tsdelta_valid = 1; + } + state->ssrc = rtp_hdr->ssrc; state->seq_offset = (state->max_seq + 1) - seq; - state->timestamp_offset = state->last_timestamp - timestamp; + state->timestamp_offset = (state->last_timestamp + tsdelta) - + timestamp; state->patch = endp->allow_patch; LOGP(DMGCP, LOGL_NOTICE, - "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", + "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d " + "from %s:%d in %d\n", ENDPOINT_NUMBER(endp), state->ssrc, state->seq_offset, - inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), endp->conn_mode); + tsdelta, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); } else { /* Compute current per-packet timestamp delta */ if (state->initialized && seq != state->max_seq) { diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8c3fa26..5666424 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -41,7 +41,7 @@ TS: 1280, dTS: 160, TS Errs: in 3, out 3 TS: 1400, dTS: 120, TS Errs: in 4, out 4 TS: 1560, dTS: 160, TS Errs: in 5, out 5 TS: 1720, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 6 -TS: 1880, dTS: 160, TS Errs: in 5, out 6 -TS: 2040, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 5 +TS: 2040, dTS: 160, TS Errs: in 5, out 5 +TS: 2200, dTS: 160, TS Errs: in 5, out 5 Done -- 1.7.9.5 From holger at freyther.de Thu Nov 21 19:40:00 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 21 Nov 2013 20:40:00 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131121194000.GB31186@xiaoyu.lan> On Thu, Nov 21, 2013 at 07:05:45PM +0100, Jacob Erlbeck wrote: > The current implementation increments the seqno but does not increment > the RTP timestamp, leading to two identical timestamps following one > after the other. thanks for spotting this! > +/* Assume audio frame length of 20ms */ > +#define RTP_AUDIO_FRAME_DUR_NUM 20 > +#define RTP_AUDIO_FRAME_DUR_DEN 1000 > +#define RTP_AUDIO_DEFAULT_RATE 8000 can't we initialize the rate in mgcp_rtp_end_init or such? This way we know that this is either default or (read from the SDP file). > state->patch = endp->allow_patch; > -TS: 2040, dTS: 160, TS Errs: in 5, out 6 > +TS: 1880, dTS: 160, TS Errs: in 5, out 5 state->patch is most likely 0 here but we do patch things. Now we might want to fix the tsdelta in all cases but then I think we should rename state->patch to state->patch_ssrc (or state->patch_stream_change)? what do you think? From jerlbeck at sysmocom.de Fri Nov 22 08:59:10 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 22 Nov 2013 09:59:10 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <20131121194000.GB31186@xiaoyu.lan> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> <20131121194000.GB31186@xiaoyu.lan> Message-ID: <528F1CDE.4060606@sysmocom.de> On 11/21/2013 08:40 PM, Holger Hans Peter Freyther wrote: > On Thu, Nov 21, 2013 at 07:05:45PM +0100, Jacob Erlbeck wrote: >> +/* Assume audio frame length of 20ms */ >> +#define RTP_AUDIO_FRAME_DUR_NUM 20 >> +#define RTP_AUDIO_FRAME_DUR_DEN 1000 >> +#define RTP_AUDIO_DEFAULT_RATE 8000 > > can't we initialize the rate in mgcp_rtp_end_init or such? This way > we know that this is either default or (read from the SDP file). We can, but then I would like to put all of the above into the rtp_end structure. > > >> state->patch = endp->allow_patch; >> -TS: 2040, dTS: 160, TS Errs: in 5, out 6 >> +TS: 1880, dTS: 160, TS Errs: in 5, out 5 > > state->patch is most likely 0 here but we do patch things. I don't know what you mean exactly, in the test case allow_patch is explicitely set. Or do you mean in the wild? > Now we might > want to fix the tsdelta in all cases but then I think we should rename > state->patch to state->patch_ssrc (or state->patch_stream_change)? > > what do you think? > Currently (with and without the patch) the packet is only patched after SSRC changes. Do you mean, that you would like to add a feature to always patch timestamps, even when the is no SSRC change? I'm not shure about the audio profiles that are to be expected, but rfc4867 allows for a lot of inconviniences w.r.t. packet durations (e.g. multiple frames per packet for a single channel). Even changing the offset after SSRC changes is just based on heuristics and may fail theoretically. If the SSRC changes when SSRC patching is disabled there is (in theory) no need to patch timestamps, since the receiver has to reinitialize timing anyway. So I conclude we have four options concerning patching: 1. Do nothing (offset is always 0) 2. Update the offset on SSRC changes and fix the SSRC 3. Check timestamps and fix them unless the SSRC changes (which is not fixed) 4. Fix SSRC and update the offset on all (detected) timestamp errors This can be divided into 2 orthogonal aspects: A. When the SSRC changes: Fix or don't fix the SSRC (including updating the offset on SSRC changes) B. When the SSRC does not change: Monitor the stream (per SSRC) for (suspected) timestamp errors and update the offset if an error is detected If the receiver was able to handle SSRC changes, we could also do the reverse to fix broken timimngs: change the SSRC on each detected timing problem. Anyway, in case B if there is a single packet in the stream which contains a different number of frames, the timing will be broken after that. So we can either a. forbid that and count packet size changes, b. disable offset updates when the packet size changes, or c. use everything we get from SDP, parse into AMR or whatever audio codec is used to determine the packet duration and use that for verification. What do you think? Jacob From holger at freyther.de Fri Nov 22 09:22:56 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 22 Nov 2013 10:22:56 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <528F1CDE.4060606@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> <20131121194000.GB31186@xiaoyu.lan> <528F1CDE.4060606@sysmocom.de> Message-ID: <20131122092256.GH31186@xiaoyu.lan> On Fri, Nov 22, 2013 at 09:59:10AM +0100, Jacob Erlbeck wrote: > We can, but then I would like to put all of the above into the rtp_end > structure. sure. > > state->patch is most likely 0 here but we do patch things. > > I don't know what you mean exactly, in the test case allow_patch is > explicitely set. Or do you mean in the wild? Now. this is what I missed then. I git grepped my local tree for allow_patch but didn't look into patch 2. > Currently (with and without the patch) the packet is only patched after > SSRC changes. It was my understanding that the TS issue we were seing also appeared without a change in the SSRC? In case this is something I asked you to do after this patch we can postpone this discussion. > just based on heuristics and may fail theoretically. SCNR: And in theory ip.access should be able to create working software with the capital they received. ;) > > If the SSRC changes when SSRC patching is disabled there is (in theory) > no need to patch timestamps, since the receiver has to reinitialize > timing anyway. true. The reason we patch the SSRC is that the nanoBTS software does not re-initialize the state. > What do you think? I would like to understand if the TS problem only occurs when the TS is changing or if the ts_delta issue is only introduced by the patching I do. From jerlbeck at sysmocom.de Fri Nov 22 09:39:00 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 22 Nov 2013 10:39:00 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <20131122092256.GH31186@xiaoyu.lan> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> <20131121194000.GB31186@xiaoyu.lan> <528F1CDE.4060606@sysmocom.de> <20131122092256.GH31186@xiaoyu.lan> Message-ID: <528F2634.7030101@sysmocom.de> On 11/22/2013 10:22 AM, Holger Hans Peter Freyther wrote: > On Fri, Nov 22, 2013 at 09:59:10AM +0100, Jacob Erlbeck wrote: > >> We can, but then I would like to put all of the above into the rtp_end >> structure. > > sure. Ok, then I'll refactor it this way. > >> Currently (with and without the patch) the packet is only patched after >> SSRC changes. > > It was my understanding that the TS issue we were seing also appeared > without a change in the SSRC? In case this is something I asked you to > do after this patch we can postpone this discussion. We've settled to just add counters and not to fix the timing for streams with a constant SSRC yet. So I'd rather put that feature into another commit after we've decided on the concept. > >> just based on heuristics and may fail theoretically. > > SCNR: And in theory ip.access should be able to create working software > with the capital they received. ;) And the audio source should deliver non-broken audio streams either. > > I would like to understand if the TS problem only occurs when the TS is > changing or if the ts_delta issue is only introduced by the patching I > do. The TS problem in question only occured within streams of a singly SSRC and are thus not fixed by the patch (but detected). I've only fixed the SSRC patching because I didn't want the osmo MGW/NAT to introduce the same kind of errors we are getting from the other audio source. Jacob From holger at freyther.de Fri Nov 22 10:05:06 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 22 Nov 2013 11:05:06 +0100 Subject: [PATCH 4/4] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <528F2634.7030101@sysmocom.de> References: <1385057145-26881-1-git-send-email-jerlbeck@sysmocom.de> <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> <20131121194000.GB31186@xiaoyu.lan> <528F1CDE.4060606@sysmocom.de> <20131122092256.GH31186@xiaoyu.lan> <528F2634.7030101@sysmocom.de> Message-ID: <20131122100506.GI31186@xiaoyu.lan> On Fri, Nov 22, 2013 at 10:39:00AM +0100, Jacob Erlbeck wrote: > I've only fixed the SSRC patching because I didn't want the osmo MGW/NAT > to introduce the same kind of errors we are getting from the other audio > source. thanks. I think we are in sync now. From y Mon Nov 25 14:19:17 2013 From: y (y) Date: Mon, 25 Nov 2013 15:19:17 +0100 Subject: [PATCH] mgcp/rtp: Fix timestamp offset when patching RTP packets In-Reply-To: <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> References: <1385057145-26881-4-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385389157-17795-1-git-send-email-y> From: Jacob Erlbeck The current implementation increments the seqno but does not increment the RTP timestamp, leading to two identical timestamps following one after the other. This patch fixes this by adding the computed tsdelta when the offset is calulated. In the unlikely case, that a tsdelta hasn't been computed yet when the SSRC changes, a tsdelta is computed based on the RTP rate and a RTP packet duration of 20ms (one speech frame per channel and packet). If the RTP rate is not known, a rate of 8000 is assumed. Note that this approach presumes, that the per RTP packet duration (in samples) is the same for the last two packets of the stream being replaced (the first one). Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 4 ++++ openbsc/src/libmgcp/mgcp_network.c | 23 +++++++++++++++++++---- openbsc/src/libmgcp/mgcp_protocol.c | 12 ++++++++++++ openbsc/tests/mgcp/mgcp_test.c | 16 +++++++++++----- openbsc/tests/mgcp/mgcp_test.ok | 6 +++--- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 8b6a56b..0b52c1c 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -77,6 +77,10 @@ struct mgcp_rtp_end { /* per endpoint data */ int payload_type; + uint32_t rate; + uint32_t frame_duration_num; + uint32_t frame_duration_den; + int frames_per_packet; char *fmtp_extra; /* diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index fa10cec..8f7fd09 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -238,15 +238,30 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->transit = arrival_time - timestamp; state->out_stream = state->in_stream; } else if (state->in_stream.ssrc != rtp_hdr->ssrc) { + int32_t tsdelta = state->out_stream.last_tsdelta; + if (tsdelta != 0) { + tsdelta = rtp_end->rate * rtp_end->frames_per_packet * + rtp_end->frame_duration_num / + rtp_end->frame_duration_den; + LOGP(DMGCP, LOGL_NOTICE, + "Computed timestamp delta %d based on " + "rate %d, num frames %d, frame duration %d/%d\n", + tsdelta, rtp_end->rate, rtp_end->frames_per_packet, + rtp_end->frame_duration_num, + rtp_end->frame_duration_den); + } state->in_stream.ssrc = rtp_hdr->ssrc; state->seq_offset = (state->out_stream.last_seq + 1) - seq; - state->timestamp_offset = state->out_stream.last_timestamp - timestamp; + state->timestamp_offset = + (state->out_stream.last_timestamp + tsdelta) - timestamp; state->patch = endp->allow_patch; LOGP(DMGCP, LOGL_NOTICE, - "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n", + "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d " + "from %s:%d in %d\n", ENDPOINT_NUMBER(endp), state->in_stream.ssrc, - state->seq_offset, inet_ntoa(addr->sin_addr), - ntohs(addr->sin_port), endp->conn_mode); + state->seq_offset, tsdelta, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); state->in_stream.last_tsdelta = 0; } else { diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 6d22cf3..71fb89d 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -40,6 +40,12 @@ for (line = strtok_r(NULL, "\r\n", &save); line;\ line = strtok_r(NULL, "\r\n", &save)) +/* Assume audio frame length of 20ms */ +#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20 +#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 +#define DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET 1 +#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000 + static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end); struct mgcp_parse_data { @@ -965,6 +971,12 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->local_alloc = -1; talloc_free(end->fmtp_extra); end->fmtp_extra = NULL; + + /* Set default values */ + end->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM; + end->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN; + end->frames_per_packet = DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET; + end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; } static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index d3c5687..84c55aa 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -417,7 +417,7 @@ static void test_packet_error_detection(void) struct mgcp_trunk_config trunk; struct mgcp_endpoint endp; struct mgcp_rtp_state state; - struct mgcp_rtp_end rtp; + struct mgcp_rtp_end *rtp = &endp.net_end; struct sockaddr_in addr = {0}; char buffer[4096]; @@ -426,14 +426,20 @@ static void test_packet_error_detection(void) memset(&trunk, 0, sizeof(trunk)); memset(&endp, 0, sizeof(endp)); memset(&state, 0, sizeof(state)); - memset(&rtp, 0, sizeof(rtp)); trunk.number_endpoints = 1; trunk.endpoints = &endp; + endp.tcfg = &trunk; + + /* This doesn't free endp but resets/frees all fields of the structure + * and invokes mgcp_rtp_end_reset() for each mgcp_rtp_end. OTOH, it + * expects valid pointer fields (either NULL or talloc'ed), so the + * memset is still needed. It also requires that endp.tcfg and + * trunk.endpoints are set up properly. */ + mgcp_free_endp(&endp); - rtp.payload_type = 98; + rtp->payload_type = 98; endp.allow_patch = 1; - endp.tcfg = &trunk; for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { struct rtp_packet_info *info = test_rtp_packets1 + i; @@ -442,7 +448,7 @@ static void test_packet_error_detection(void) OSMO_ASSERT(info->len >= 0); memmove(buffer, info->data, info->len); - mgcp_patch_and_count(&endp, &state, &rtp, &addr, + mgcp_patch_and_count(&endp, &state, rtp, &addr, buffer, info->len); printf("TS: %d, dTS: %d, TS Errs: in %d, out %d\n", diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 8c3fa26..5666424 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -41,7 +41,7 @@ TS: 1280, dTS: 160, TS Errs: in 3, out 3 TS: 1400, dTS: 120, TS Errs: in 4, out 4 TS: 1560, dTS: 160, TS Errs: in 5, out 5 TS: 1720, dTS: 160, TS Errs: in 5, out 5 -TS: 1720, dTS: 160, TS Errs: in 5, out 6 -TS: 1880, dTS: 160, TS Errs: in 5, out 6 -TS: 2040, dTS: 160, TS Errs: in 5, out 6 +TS: 1880, dTS: 160, TS Errs: in 5, out 5 +TS: 2040, dTS: 160, TS Errs: in 5, out 5 +TS: 2200, dTS: 160, TS Errs: in 5, out 5 Done -- 1.7.9.5 From jerlbeck at sysmocom.de Mon Nov 25 12:12:43 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 25 Nov 2013 13:12:43 +0100 Subject: [PATCH] libabis: Enable TCP keepalive by default on all BTS connections Message-ID: <1385381563-28967-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 4a56569..371b21c 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. @@ -605,7 +610,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; @@ -638,6 +643,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 andrew at carrierdetect.com Thu Nov 28 11:17:31 2013 From: andrew at carrierdetect.com (Andrew Back) Date: Thu, 28 Nov 2013 11:17:31 +0000 Subject: Creating a graphic of Osmocom GSM projects. Message-ID: Hello, I'm working on producing a graphic which shows Osmocom projects that can be used in a production GSM network, along with related projects that are used together with these. I'd also like to show these in the context of legacy networks, e.g. with existing BSC and MSC etc. First, I need to be sure I have the complete list: ? Osmocom * BSC (or much more): OpenBSC (osmo-bsc or NITB) * BTS: OsmoBTS + sysmoBTS or osmo-trx/UmTRX in Fairwaves solution * PCU: osmo-pcu * SGSN: OsmoSGSN * GGSN: OpenGGSN * ??: cellmgr_ng (what would be the best use cases to show? E.g. as in bsc_nat diagram) * ??: bsc_nat (show as in diagram on wiki? Perhaps with fewer elements...) * ??: osmo-gbproxy Not sure about the status of osmocom-lcs? ? Ecosystem (supporting projects) * Linux Call Router * FreeSWITCH * Telscale SS7 card (for interfacing with legacy networks) ? Legacy * nanoBTS and others * BSC * MSC * ... ? The idea would be to try and show as many use cases as is reasonably possible and without making the graphic a mess. I'd appreciate any comments and suggestions folks may have. Cheers, Andrew -- Andrew Back http://carrierdetect.com From Max.Suraev at fairwaves.ru Thu Nov 28 11:28:56 2013 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Thu, 28 Nov 2013 12:28:56 +0100 Subject: Creating a graphic of Osmocom GSM projects. In-Reply-To: References: Message-ID: <529728F8.5090102@fairwaves.ru> osmocom-bb (rssi) could be added to picture as cell monitoring. Probably also sqlite db is worth pointing explicitly as a substitution of hlr/vlr. Looking forward to see you graphics :) 28.11.2013 12:17, Andrew Back ?????: > Hello, > > I'm working on producing a graphic which shows Osmocom projects that > can be used in a production GSM network, along with related projects > that are used together with these. I'd also like to show these in the > context of legacy networks, e.g. with existing BSC and MSC etc. > > First, I need to be sure I have the complete list: > > ? Osmocom > > * BSC (or much more): OpenBSC (osmo-bsc or NITB) > * BTS: OsmoBTS + sysmoBTS or osmo-trx/UmTRX in Fairwaves solution > * PCU: osmo-pcu > * SGSN: OsmoSGSN > * GGSN: OpenGGSN > * ??: cellmgr_ng (what would be the best use cases to show? E.g. as in > bsc_nat diagram) > * ??: bsc_nat (show as in diagram on wiki? Perhaps with fewer elements...) > * ??: osmo-gbproxy > > Not sure about the status of osmocom-lcs? > > ? Ecosystem (supporting projects) > > * Linux Call Router > * FreeSWITCH > * Telscale SS7 card (for interfacing with legacy networks) > > ? Legacy > > * nanoBTS and others > * BSC > * MSC > * ... ? > > The idea would be to try and show as many use cases as is reasonably > possible and without making the graphic a mess. > > I'd appreciate any comments and suggestions folks may have. > > Cheers, > > Andrew > -- best regards, Max, http://fairwaves.ru From jerlbeck at sysmocom.de Fri Nov 29 12:43:43 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:43 +0100 Subject: [PATCH 1/8] mgcp: Rename for_each_line to for_each_non_empty_line Message-ID: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> The implementation of for_each_line is based on strtok() and skips any sequence of CR and LF. Thus empty lines are never detected. There exists code which tests for an empty line to detect the beginning of the SDP part which is dead code currently (the parser works nevertheless due to other reasons). So the semantics of this macro have been misunderstood at least once. This patch renames the macro to reflect the semantics more precisely. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 7096495..c040ab1 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -36,7 +36,7 @@ #include #include -#define for_each_line(line, save) \ +#define for_each_non_empty_line(line, save) \ for (line = strtok_r(NULL, "\r\n", &save); line;\ line = strtok_r(NULL, "\r\n", &save)) @@ -527,7 +527,7 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) return create_err_response(NULL, 510, "CRCX", p->trans); /* parse CallID C: and LocalParameters L: */ - for_each_line(line, p->save) { + for_each_non_empty_line(line, p->save) { switch (line[0]) { case 'L': local_options = (const char *) line + 3; @@ -652,7 +652,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) return create_err_response(endp, 400, "MDCX", p->trans); } - for_each_line(line, p->save) { + for_each_non_empty_line(line, p->save) { switch (line[0]) { case 'C': { if (verify_call_id(endp, line + 3) != 0) @@ -771,7 +771,7 @@ static struct msgb *handle_delete_con(struct mgcp_parse_data *p) return create_err_response(endp, 400, "DLCX", p->trans); } - for_each_line(line, p->save) { + for_each_non_empty_line(line, p->save) { switch (line[0]) { case 'C': if (verify_call_id(endp, line + 3) != 0) @@ -873,7 +873,7 @@ static struct msgb *handle_noti_req(struct mgcp_parse_data *p) if (p->found != 0) return create_err_response(NULL, 400, "RQNT", p->trans); - for_each_line(line, p->save) { + for_each_non_empty_line(line, p->save) { switch (line[0]) { case 'S': tone = extract_tone(line); @@ -1218,7 +1218,7 @@ int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, return -1; /* this can only parse the message that is created above... */ - for_each_line(line, save) { + for_each_non_empty_line(line, save) { switch (line[0]) { case 'P': rc = sscanf(line, "P: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u", -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:44 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:44 +0100 Subject: [PATCH 2/8] mgcp: Add new for_each_line macro that also returns empty lines In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-2-git-send-email-jerlbeck@sysmocom.de> This patch add the for_each_line macro based on a strline_r() function (similar to strtok_r()), that is also part of this patch. This strline_r() function is tolerant with respect to line endings, it supports CR-only, CRLF, and LF-only and any combinations thereof (note that a CRLF is always detected as a single line break). Similar to for_each_non_empty_line (the former for_each_line) where the 'save' pointer needed to be initialised by a call to strtok_r(), the new for_each_line macro expects, that the 'save' pointer has been initialised by a call to strline_r(). Also note, that for_each_line/strline_r and for_each_non_empty_line/strtok_r may use the 'save' pointer differently, so calls to them can not be mixed. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 32 ++++++++++++++++++++++++++++++++ openbsc/tests/mgcp/mgcp_test.c | 35 +++++++++++++++++++++++++++++++++++ openbsc/tests/mgcp/mgcp_test.ok | 13 +++++++++++++ 3 files changed, 80 insertions(+) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index c040ab1..19a6f53 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -40,6 +40,38 @@ for (line = strtok_r(NULL, "\r\n", &save); line;\ line = strtok_r(NULL, "\r\n", &save)) +#define for_each_line(line, save) \ + for (line = strline_r(NULL, &save); line;\ + line = strline_r(NULL, &save)) + +char *strline_r(char *str, char **saveptr) +{ + char *result; + + if (str) + *saveptr = str; + + result = *saveptr; + + if (*saveptr != NULL) { + *saveptr = strpbrk(*saveptr, "\r\n"); + + if (*saveptr != NULL) { + char *eos = *saveptr; + + if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n') + (*saveptr)++; + (*saveptr)++; + if ((*saveptr)[0] == '\0') + *saveptr = NULL; + + *eos = '\0'; + } + } + + return result; +} + /* Assume audio frame length of 20ms */ #define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20 #define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index d36aaa8..362f029 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -25,6 +25,40 @@ #include #include +char *strline_r(char *str, char **saveptr); + +const char *strline_test_data = + "one CR\r" + "two CR\r" + "\r" + "one CRLF\r\n" + "two CRLF\r\n" + "\r\n" + "one LF\n" + "two LF\n" + "\n" + "mixed (4 lines)\r\r\n\n\r\n"; + +#define EXPECTED_NUMBER_OF_LINES 13 + +static void test_strline(void) +{ + char *save = NULL; + char *line; + char buf[2048]; + int counter = 0; + + strncpy(buf, strline_test_data, sizeof(buf)); + + for (line = strline_r(buf, &save); line; + line = strline_r(NULL, &save)) { + printf("line: '%s'\n", line); + counter++; + } + + OSMO_ASSERT(counter == EXPECTED_NUMBER_OF_LINES); +} + #define AUEP1 "AUEP 158663169 ds/e1-1/2 at 172.16.6.66 MGCP 1.0\r\n" #define AUEP1_RET "200 158663169 OK\r\n" #define AUEP2 "AUEP 18983213 ds/e1-2/1 at 172.16.6.66 MGCP 1.0\r\n" @@ -463,6 +497,7 @@ int main(int argc, char **argv) { osmo_init_logging(&log_info); + test_strline(); test_messages(); test_retransmission(); test_packet_loss_calc(); diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 5666424..429e0df 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -1,3 +1,16 @@ +line: 'one CR' +line: 'two CR' +line: '' +line: 'one CRLF' +line: 'two CRLF' +line: '' +line: 'one LF' +line: 'two LF' +line: '' +line: 'mixed (4 lines)' +line: '' +line: '' +line: '' Testing AUEP1 Testing AUEP2 Testing MDCX1 -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:45 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:45 +0100 Subject: [PATCH 3/8] mgcp: Add tests for payload types in MGCP messages In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-3-git-send-email-jerlbeck@sysmocom.de> These tests mainly check whether the SDP parsing works properly by looking at the payload type detected. Sponsored-by: On-Waves ehf --- openbsc/tests/bsc-nat/bsc_data.c | 5 +++ openbsc/tests/bsc-nat/bsc_nat_test.c | 16 ++++++- openbsc/tests/mgcp/mgcp_test.c | 82 +++++++++++++++++++++++++++++++--- openbsc/tests/mgcp/mgcp_test.ok | 1 + 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c index 5a76689..d1f8ebc 100644 --- a/openbsc/tests/bsc-nat/bsc_data.c +++ b/openbsc/tests/bsc-nat/bsc_data.c @@ -177,6 +177,7 @@ struct mgcp_patch_test { const char *patch; const char *ip; const int port; + const int payload_type; }; static const struct mgcp_patch_test mgcp_messages[] = { @@ -191,24 +192,28 @@ static const struct mgcp_patch_test mgcp_messages[] = { .patch = crcx_resp_patched, .ip = "10.0.0.1", .port = 999, + .payload_type = 98, }, { .orig = mdcx, .patch = mdcx_patched, .ip = "10.0.0.23", .port = 6666, + .payload_type = 126, }, { .orig = mdcx_resp, .patch = mdcx_resp_patched, .ip = "10.0.0.23", .port = 5555, + .payload_type = 98, }, { .orig = mdcx_resp2, .patch = mdcx_resp_patched2, .ip = "10.0.0.23", .port = 5555, + .payload_type = 98, }, }; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index 5158f46..3320e06 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -624,10 +624,24 @@ static void test_mgcp_rewrite(void) const char *patc = mgcp_messages[i].patch; const char *ip = mgcp_messages[i].ip; const int port = mgcp_messages[i].port; + const int expected_payload_type = mgcp_messages[i].payload_type; + int payload_type = -1; char *input = strdup(orig); - output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port); + output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, + ip, port); + + if (payload_type != -1) { + fprintf(stderr, "Found media payload type %d in SDP data\n", + payload_type); + if (payload_type != expected_payload_type) { + printf("Wrong payload type %d (expected %d)\n", + payload_type, expected_payload_type); + abort(); + } + } + if (msgb_l2len(output) != strlen(patc)) { printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig)); printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc); diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 362f029..0aebb4c 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -82,6 +82,26 @@ static void test_strline(void) "t=0 0\r\n" \ "m=audio 0 RTP/AVP 126\r\n" \ "a=rtpmap:126 AMR/8000\r\n" +#define MDCX4 "MDCX 18983216 1 at mgw MGCP 1.0\r\n" \ + "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" +#define MDCX4_RET "200 18983216 OK\r\n" \ + "I: 1\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 0 RTP/AVP 126\r\n" \ + "a=rtpmap:126 AMR/8000\r\n" #define SHORT2 "CRCX 1" #define SHORT2_RET "510 000000 FAIL\r\n" @@ -145,10 +165,16 @@ static void test_strline(void) #define RQNT1_RET "200 186908780 OK\r\n" #define RQNT2_RET "200 186908781 OK\r\n" +#define PTYPE_IGNORE 0 /* == default initializer */ +#define PTYPE_NONE 128 +#define PTYPE_NYI PTYPE_NONE + struct mgcp_test { const char *name; const char *req; const char *exp_resp; + int exp_net_ptype; + int exp_bts_ptype; }; static const struct mgcp_test tests[] = { @@ -156,10 +182,11 @@ static const struct mgcp_test tests[] = { { "AUEP2", AUEP2, AUEP2_RET }, { "MDCX1", MDCX_WRONG_EP, MDCX_ERR_RET }, { "MDCX2", MDCX_UNALLOCATED, MDCX_RET }, - { "CRCX", CRCX, CRCX_RET }, - { "MDCX3", MDCX3, MDCX3_RET }, - { "DLCX", DLCX, DLCX_RET }, - { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET }, + { "CRCX", CRCX, CRCX_RET, PTYPE_NYI, 126 }, + { "MDCX3", MDCX3, MDCX3_RET, PTYPE_NONE, 126 }, + { "MDCX4", MDCX4, MDCX4_RET, 99, 126 }, + { "DLCX", DLCX, DLCX_RET, -1, -1 }, + { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, PTYPE_NYI, 126 }, { "EMPTY", EMPTY, EMPTY_RET }, { "SHORT1", SHORT, SHORT_RET }, { "SHORT2", SHORT2, SHORT2_RET }, @@ -167,7 +194,7 @@ static const struct mgcp_test tests[] = { { "SHORT4", SHORT4, SHORT2_RET }, { "RQNT1", RQNT, RQNT1_RET }, { "RQNT2", RQNT2, RQNT2_RET }, - { "DLCX", DLCX, DLCX_RET }, + { "DLCX", DLCX, DLCX_RET, -1, -1 }, }; static const struct mgcp_test retransmit[] = { @@ -188,9 +215,21 @@ static struct msgb *create_msg(const char *str) return msg; } +static int last_endpoint = -1; + +static int mgcp_test_policy_cb(struct mgcp_trunk_config *cfg, int endpoint, + int state, const char *transactio_id) +{ + fprintf(stderr, "Policy CB got state %d on endpoint %d\n", + state, endpoint); + last_endpoint = endpoint; + return MGCP_POLICY_CONT; +} + static void test_messages(void) { struct mgcp_config *cfg; + struct mgcp_endpoint *endp; int i; cfg = mgcp_config_alloc(); @@ -198,8 +237,16 @@ static void test_messages(void) cfg->trunk.number_endpoints = 64; mgcp_endpoints_allocate(&cfg->trunk); + cfg->policy_cb = mgcp_test_policy_cb; + mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1)); + /* reset endpoints */ + for (i = 0; i < cfg->trunk.number_endpoints; i++) { + endp = &cfg->trunk.endpoints[i]; + endp->net_end.payload_type = PTYPE_NONE; + } + for (i = 0; i < ARRAY_SIZE(tests); i++) { const struct mgcp_test *t = &tests[i]; struct msgb *inp; @@ -207,6 +254,8 @@ static void test_messages(void) printf("Testing %s\n", t->name); + last_endpoint = -1; + inp = create_msg(t->req); msg = mgcp_handle_message(cfg, inp); msgb_free(inp); @@ -216,6 +265,29 @@ static void test_messages(void) } else if (strcmp((char *) msg->data, t->exp_resp) != 0) printf("%s failed '%s'\n", t->name, (char *) msg->data); msgb_free(msg); + + /* Check detected payload type */ + if (t->exp_net_ptype != PTYPE_IGNORE || + t->exp_bts_ptype != PTYPE_IGNORE) { + OSMO_ASSERT(last_endpoint != -1); + endp = &cfg->trunk.endpoints[last_endpoint]; + + fprintf(stderr, "endpoint %d: " + "payload type BTS %d (exp %d), NET %d (exp %d)\n", + last_endpoint, + endp->bts_end.payload_type, t->exp_bts_ptype, + endp->net_end.payload_type, t->exp_net_ptype); + + if (t->exp_bts_ptype != PTYPE_IGNORE) + OSMO_ASSERT(endp->bts_end.payload_type == + t->exp_bts_ptype); + if (t->exp_net_ptype != PTYPE_IGNORE) + OSMO_ASSERT(endp->net_end.payload_type == + t->exp_net_ptype); + + /* Reset them again for next test */ + endp->net_end.payload_type = PTYPE_NONE; + } } talloc_free(cfg); diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 429e0df..3bfd78b 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -17,6 +17,7 @@ Testing MDCX1 Testing MDCX2 Testing CRCX Testing MDCX3 +Testing MDCX4 Testing DLCX Testing CRCX_ZYN Testing EMPTY -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:46 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:46 +0100 Subject: [PATCH 4/8] mgcp: Refactor MGCP/SDP parsing In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-4-git-send-email-jerlbeck@sysmocom.de> This patch separates the SDP parsing from the (message specific) MGCP parsing. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 98 +++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 19a6f53..d4a23a7 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -282,7 +282,7 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg) */ memset(&pdata, 0, sizeof(pdata)); pdata.cfg = cfg; - data = strtok_r((char *) msg->l3h, "\r\n", &pdata.save); + data = strline_r((char *) msg->l3h, &pdata.save); pdata.found = mgcp_analyze_header(&pdata, data); if (pdata.endp && pdata.trans && pdata.endp->last_trans @@ -544,6 +544,62 @@ static int allocate_ports(struct mgcp_endpoint *endp) return 0; } +static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) +{ + char *line; + int found_media = 0; + + for_each_line(line, p->save) { + switch (line[0]) { + case 'a': + case 'o': + case 's': + case 't': + case 'v': + /* skip these SDP attributes */ + break; + case 'm': { + int port; + int payload; + + if (sscanf(line, "m=audio %d RTP/AVP %d", + &port, &payload) == 2) { + rtp->rtp_port = htons(port); + rtp->rtcp_port = htons(port + 1); + rtp->payload_type = payload; + found_media = 1; + } + break; + } + case 'c': { + char ipv4[16]; + + if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) { + inet_aton(ipv4, &rtp->addr); + } + break; + } + default: + if (p->endp) + LOGP(DMGCP, LOGL_NOTICE, + "Unhandled SDP option: '%c'/%d on 0x%x\n", + line[0], line[0], ENDPOINT_NUMBER(p->endp)); + else + LOGP(DMGCP, LOGL_NOTICE, + "Unhandled SDP option: '%c'/%d\n", + line[0], line[0]); + break; + } + } + + if (found_media) + LOGP(DMGCP, LOGL_NOTICE, + "Got media info via SDP: port %d, payload %d, addr %s\n", + ntohs(rtp->rtp_port), rtp->payload_type, inet_ntoa(rtp->addr)); + + return found_media; +} + static struct msgb *handle_create_con(struct mgcp_parse_data *p) { struct mgcp_trunk_config *tcfg; @@ -559,7 +615,7 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) return create_err_response(NULL, 510, "CRCX", p->trans); /* parse CallID C: and LocalParameters L: */ - for_each_non_empty_line(line, p->save) { + for_each_line(line, p->save) { switch (line[0]) { case 'L': local_options = (const char *) line + 3; @@ -684,7 +740,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) return create_err_response(endp, 400, "MDCX", p->trans); } - for_each_non_empty_line(line, p->save) { + for_each_line(line, p->save) { switch (line[0]) { case 'C': { if (verify_call_id(endp, line + 3) != 0) @@ -711,35 +767,13 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) break; case '\0': /* SDP file begins */ + parse_sdp_data(&endp->net_end, p); + /* This will exhaust p->save, so the loop will + * terminate next time. + */ break; - case 'a': - case 'o': - case 's': - case 't': - case 'v': - /* skip these SDP attributes */ - break; - case 'm': { - int port; - int payload; - - if (sscanf(line, "m=audio %d RTP/AVP %d", &port, &payload) == 2) { - endp->net_end.rtp_port = htons(port); - endp->net_end.rtcp_port = htons(port + 1); - endp->net_end.payload_type = payload; - } - break; - } - case 'c': { - char ipv4[16]; - - if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) { - inet_aton(ipv4, &endp->net_end.addr); - } - break; - } default: - LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n", + LOGP(DMGCP, LOGL_NOTICE, "Unhandled MGCP option: '%c'/%d on 0x%x\n", line[0], line[0], ENDPOINT_NUMBER(endp)); break; } @@ -803,7 +837,7 @@ static struct msgb *handle_delete_con(struct mgcp_parse_data *p) return create_err_response(endp, 400, "DLCX", p->trans); } - for_each_non_empty_line(line, p->save) { + for_each_line(line, p->save) { switch (line[0]) { case 'C': if (verify_call_id(endp, line + 3) != 0) @@ -905,7 +939,7 @@ static struct msgb *handle_noti_req(struct mgcp_parse_data *p) if (p->found != 0) return create_err_response(NULL, 400, "RQNT", p->trans); - for_each_non_empty_line(line, p->save) { + for_each_line(line, p->save) { switch (line[0]) { case 'S': tone = extract_tone(line); -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:47 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:47 +0100 Subject: [PATCH 5/8] mgcp: NUL-terminate MGCP message In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-5-git-send-email-jerlbeck@sysmocom.de> The MGCP message isn't always NUL-terminated when arriving at mgcp_handle_message(). This may lead to undefined results. This patch ensures that the message text is NUL-terminated by setting *msg->tail to '\0' in mgcp_handle_message(). Addresses: <000b> mgcp_protocol.c:642 Unhandled option: 'r'/114 on 0x3 <000b> mgcp_protocol.c:593 Unhandled SDP option: '='/61 on 0x3 <000b> mgcp_protocol.c:871 Unhandled option: '.'/46 on 0x2 Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index d4a23a7..44c93f7 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -262,6 +262,18 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg) struct msgb *resp = NULL; char *data; + /* Ensure that the msg->l2h is NULL terminated. */ + if (msgb_tailroom(msg) > 0) + *msg->tail = '\0'; + else if (*(msg->tail-1) == '\r' || *(msg->tail-1) == '\n') + *(msg->tail - 1) = '\0'; + else { + LOGP(DMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: " + "Length: %d, Buffer size: %d\n", + msgb_l2len(msg), msg->data_len); + return NULL; + } + if (msgb_l2len(msg) < 4) { LOGP(DMGCP, LOGL_ERROR, "msg too short: %d\n", msg->len); return NULL; @@ -278,7 +290,6 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg) /* * Check for a duplicate message and respond. - * FIXME: Verify that the msg->l3h is NULL terminated. */ memset(&pdata, 0, sizeof(pdata)); pdata.cfg = cfg; -- 1.7.9.5 From holger at freyther.de Sat Nov 30 18:16:22 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 30 Nov 2013 19:16:22 +0100 Subject: [PATCH 5/8] mgcp: NUL-terminate MGCP message In-Reply-To: <1385729030-5155-5-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> <1385729030-5155-5-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131130181622.GF5460@xiaoyu.lan> On Fri, Nov 29, 2013 at 01:43:47PM +0100, Jacob Erlbeck wrote: > The MGCP message isn't always NUL-terminated when arriving at > mgcp_handle_message(). This may lead to undefined results. oh! > + /* Ensure that the msg->l2h is NULL terminated. */ > + if (msgb_tailroom(msg) > 0) > + *msg->tail = '\0'; > + else if (*(msg->tail-1) == '\r' || *(msg->tail-1) == '\n') > + *(msg->tail - 1) = '\0'; > + else { > + LOGP(DMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: " > + "Length: %d, Buffer size: %d\n", > + msgb_l2len(msg), msg->data_len); > + return NULL; > + } The check misses if "tail - 1" is already \0 and if tail - 1 is not NULL. I would just add an OSMO_ASSERT and fix the caller that didn't null terminate?! What do you think? From jerlbeck at sysmocom.de Fri Nov 29 12:43:48 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:48 +0100 Subject: [PATCH 6/8] mgcp/nat: Take payload type from SDP data In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-6-git-send-email-jerlbeck@sysmocom.de> So far the payload type used in RTP streams has been taken from the trunk configuration in NAT mode. This patch changes the implementation to use the payload type announced in the SDP part of MGCP messages and responses. SDP descriptions more than one m=audio line are not yet supported properly (always the last one is taken). Ticket: OW#466 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/bsc_nat.h | 3 ++- openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c | 17 +++++++++++++---- openbsc/tests/bsc-nat/bsc_nat_test.c | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 635b125..150979b 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -408,7 +408,8 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat); int bsc_mgcp_nat_init(struct bsc_nat *nat); struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number); -struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip, int port); +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip, + int port, int *payload_type); void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg); void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc); diff --git a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c index 8bb6075..3dad396 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c +++ b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c @@ -542,8 +542,10 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int } /* we need to generate a new and patched message */ - bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, sccp->bsc_endp, - nat->mgcp_cfg->source_addr, mgcp_endp->bts_end.local_port); + bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, + sccp->bsc_endp, nat->mgcp_cfg->source_addr, + mgcp_endp->bts_end.local_port, + &mgcp_endp->net_end.payload_type); if (!bsc_msg) { LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n"); return MGCP_POLICY_CONT; @@ -683,7 +685,9 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) * with the value of 0 should be no problem. */ output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), -1, - bsc->nat->mgcp_cfg->source_addr, endp->net_end.local_port); + bsc->nat->mgcp_cfg->source_addr, + endp->net_end.local_port, + &endp->bts_end.payload_type); if (!output) { LOGP(DMGCP, LOGL_ERROR, "Failed to rewrite MGCP msg.\n"); @@ -743,7 +747,9 @@ static void patch_mgcp(struct msgb *output, const char *op, const char *tok, } /* we need to replace some strings... */ -struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char *ip, int port) +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, + const char *ip, int port, + int *payload_type) { static const char crcx_str[] = "CRCX "; static const char dlcx_str[] = "DLCX "; @@ -836,6 +842,9 @@ copy: memcpy(output->l3h, buf, strlen(buf)); } + if (payload != -1 && payload_type) + *payload_type = payload; + return output; } diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index 3320e06..a121c8a 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -630,7 +630,7 @@ static void test_mgcp_rewrite(void) char *input = strdup(orig); output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, - ip, port); + ip, port, &payload_type); if (payload_type != -1) { fprintf(stderr, "Found media payload type %d in SDP data\n", -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:49 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:49 +0100 Subject: [PATCH 7/8] mgcp: Handle SDP in CRCX received by the MGW In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-7-git-send-email-jerlbeck@sysmocom.de> So far the SDP part of the CRCX message has been ignored by the MGW. This patch adds SDP parsing for this case, eventually updating the net end's payload type and connection parameters. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_protocol.c | 9 +++++++++ openbsc/tests/mgcp/mgcp_test.c | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 44c93f7..270f4bc 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -621,6 +621,7 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) const char *callid = NULL; const char *mode = NULL; char *line; + int have_sdp = 0; if (p->found != 0) return create_err_response(NULL, 510, "CRCX", p->trans); @@ -637,6 +638,9 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) case 'M': mode = (const char *) line + 3; break; + case '\0': + have_sdp = 1; + goto mgcp_header_done; default: LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n", *line, *line, ENDPOINT_NUMBER(endp)); @@ -644,6 +648,7 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) } } +mgcp_header_done: tcfg = p->endp->tcfg; /* Check required data */ @@ -694,9 +699,13 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p) goto error2; endp->allocated = 1; + + /* set up RTP media parameters */ endp->bts_end.payload_type = tcfg->audio_payload; endp->bts_end.fmtp_extra = talloc_strdup(tcfg->endpoints, tcfg->audio_fmtp_extra); + if (have_sdp) + parse_sdp_data(&endp->net_end, p); /* policy CB */ if (p->cfg->policy_cb) { diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 0aebb4c..c58f52d 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -182,11 +182,11 @@ static const struct mgcp_test tests[] = { { "AUEP2", AUEP2, AUEP2_RET }, { "MDCX1", MDCX_WRONG_EP, MDCX_ERR_RET }, { "MDCX2", MDCX_UNALLOCATED, MDCX_RET }, - { "CRCX", CRCX, CRCX_RET, PTYPE_NYI, 126 }, + { "CRCX", CRCX, CRCX_RET, 97, 126 }, { "MDCX3", MDCX3, MDCX3_RET, PTYPE_NONE, 126 }, { "MDCX4", MDCX4, MDCX4_RET, 99, 126 }, { "DLCX", DLCX, DLCX_RET, -1, -1 }, - { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, PTYPE_NYI, 126 }, + { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, 97, 126 }, { "EMPTY", EMPTY, EMPTY_RET }, { "SHORT1", SHORT, SHORT_RET }, { "SHORT2", SHORT2, SHORT2_RET }, -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 12:43:50 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 13:43:50 +0100 Subject: [PATCH 8/8] mgcp: Fix output timing error counter In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1385729030-5155-8-git-send-email-jerlbeck@sysmocom.de> The tsdelta computation and error detection didn't handle the intialisation phase properly. This patches fixes this by skipping the output timing validation for the first packet. Sponsored-by: On-Waves ehf --- openbsc/src/libmgcp/mgcp_network.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 75d39c1..1ce9cc2 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -219,6 +219,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta uint32_t timestamp; struct rtp_hdr *rtp_hdr; int payload = rtp_end->payload_type; + int initializing = 0; if (len < sizeof(*rtp_hdr)) return; @@ -229,6 +230,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta arrival_time = get_current_ts(); if (!state->initialized) { + initializing = 1; state->in_stream.last_seq = seq - 1; state->in_stream.ssrc = state->orig_ssrc = rtp_hdr->ssrc; state->in_stream.last_tsdelta = 0; @@ -237,6 +239,14 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta state->jitter = 0; state->transit = arrival_time - timestamp; state->out_stream = state->in_stream; + state->out_stream.last_timestamp = timestamp; + LOGP(DMGCP, LOGL_INFO, + "Initializing stream on 0x%x SSRC: %u timestamp: %u " + "from %s:%d in %d\n", + ENDPOINT_NUMBER(endp), state->in_stream.ssrc, + state->seq_offset, + inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), + endp->conn_mode); } else if (state->in_stream.ssrc != rtp_hdr->ssrc) { int32_t tsdelta = state->out_stream.last_tsdelta; if (tsdelta == 0) { @@ -286,9 +296,10 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta } /* Check again, whether the timestamps are still valid */ - check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr, - seq, timestamp, "output", - &state->out_stream.last_tsdelta); + if (!initializing) + check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr, + seq, timestamp, "output", + &state->out_stream.last_tsdelta); /* * The below takes the shape of the validation from Appendix A. Check -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Nov 29 13:15:58 2013 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 29 Nov 2013 14:15:58 +0100 Subject: [PATCH 8/8] mgcp: Fix output timing error counter In-Reply-To: <1385729030-5155-8-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> <1385729030-5155-8-git-send-email-jerlbeck@sysmocom.de> Message-ID: <5298938E.7070407@sysmocom.de> Hi Holger, please do not apply this one. It will most likely be solved differently soon. Jacob On 11/29/2013 01:43 PM, Jacob Erlbeck wrote: > The tsdelta computation and error detection didn't handle the > intialisation phase properly. > > This patches fixes this by skipping the output timing validation for > the first packet. > > Sponsored-by: On-Waves ehf > --- From holger at freyther.de Sat Nov 30 18:08:04 2013 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 30 Nov 2013 19:08:04 +0100 Subject: [PATCH 1/8] mgcp: Rename for_each_line to for_each_non_empty_line In-Reply-To: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> References: <1385729030-5155-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20131130180804.GE5460@xiaoyu.lan> On Fri, Nov 29, 2013 at 01:43:43PM +0100, Jacob Erlbeck wrote: > The implementation of for_each_line is based on strtok() and skips > any sequence of CR and LF. Thus empty lines are never detected. There > exists code which tests for an empty line to detect the beginning of > the SDP part which is dead code currently (the parser works > nevertheless due to other reasons). So the semantics of this macro > have been misunderstood at least once. > > This patch renames the macro to reflect the semantics more precisely. Do you want to remove the "case '\0':" lines (just to add them in later commits again)?